Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: С Left Joinом не понятка

Привет всем
Помогите c Left Joinом не понятка
Firebird 3 RC2

Есть таблица Items пример
ID
NM
REFCATEGORYID
REFMEASURMENTID
VISIBLE  //0 Не виден,1 Виден

REFCATEGORY
ID 
NM

REFMEASURMENT
ID
NM


Делаю селект

select * from items a
left join REFCATEGORY b on a.REFCATEGORYID=b.id
left join REFMEASURMENT c on a.REFMEASURMENTID=c.id
and a.visible=1


Почему то это критерия не работает and a.visible=1
Показывает все записи

Времмено решил так
select * from (select from )
Ответ: Спасибо всем
Вопрос: Какая разница между Left Join и Right Join

Нашел в документации такое:
автор
RIGHT JOIN реализован аналогично LEFT JOIN.

А про LEFT JOIN пишут такое :
автор
Выражение "A LEFT JOIN B" в MySQL реализовано следующим образом:
...
Таблица B устанавливается как зависимая от таблицы A и от всех таблиц, от которых зависит A.
....
Выполняются все стандартные способы оптимизации соединения, за исключением того, что таблица всегда читается после всех таблиц, от которых она зависит.

Получается таблица А используя LEFT JOIN будет читаться первой, но и в запросе "A RIGHT JOIN B" таблица А все равно будет читаться первой.
Поэтому:
SELECT * FROM
    t1 RIGHT JOIN t2
    USING (blah_id)

будет выполнятся с такой же скоростью что и запрос:
SELECT * FROM
    t1 LEFT JOIN t2
    USING (blah_id)
    WHERE t2.blah_id IS NOT NULL


Я правильно понял?
Ответ:
Vano34
Получается таблица А используя LEFT JOIN будет читаться первой, но и в запросе "A RIGHT JOIN B" таблица А все равно будет читаться первой.
Нет. Всегда первой читается ЛЕВАЯ таблица.
Vano34
А еще там было написано, что предпочтительнее использовать LEFT JOIN

Да. Это снимает видимую неоднозначность при смешении типов соединений и отсутствии задающих порядок соединения скобок.
Впрочем, парсер-оптимизатору по барабану. Первое, что он сделает - это трансформирует текст запроса во внутренний псевдокод, а там нет правого и левого связываний, это одно и то же связывание.
Вопрос: Как запросить LEFT JOIN на одну и туже таблицу для разных значений id?

Вот запрос, будет ли он корректен?
В таблице `свадьба` есть id жениха и id невесты.
Нужно вывести их id плюс вывести еще и их фамилии, которые находятся в другой таблице `фамилии`.
В таблице `фамилии` есть поля `id_пользователя` и `ФИО`

SELECT 
`свадьба`.`id_жених`,
`свадьба`.`id_невеста` 

`фамилии`.`ФИО` as ФИО_жениха,
`фамилии`.`ФИО` as ФИО_невесты

FROM `свадьба`

LEFT JOIN `фамилии` ON `фамилии`.`id_жених` = `фамилии`.`id_пользователя`
LEFT JOIN `фамилии` ON `фамилии`.`id_невеста` = `фамилии`.`id_пользователя`

WHERE `свадьба`.`id_свадьбы`= 15
Ответ:
manking
Вот запрос, будет ли он корректен?
В таблице `свадьба` есть id жениха и id невесты.
Нужно вывести их id плюс вывести еще и их фамилии, которые находятся в другой таблице `фамилии`.
В таблице `фамилии` есть поля `id_пользователя` и `ФИО`

SELECT 
`свадьба`.`id_жених`,
`свадьба`.`id_невеста` 

m.`ФИО` as ФИО_жениха,
w.`ФИО` as ФИО_невесты

FROM `свадьба`

LEFT JOIN `фамилии` m ON `свадьба`.`id_жених` = m.`id_пользователя`
LEFT JOIN `фамилии` w ON `свадьба`.`id_невеста` = w.`id_пользователя`

WHERE `свадьба`.`id_свадьбы`= 15
Вопрос: Множественны LEFT JOIN в ACCESS

Волей судеб пришлось поработать в ЭТОМ... Пытаюсь к одной таблице присоединить несколько других, набираю на честном SQL следующий запрос

SELECT d.id_device, c.city, s.street, st.street_type, b.building, e.entrance
FROM device AS d 
LEFT JOIN city AS c ON d.id_city=c.id_city
LEFT JOIN street AS s ON d.id_street=s.id_street
LEFT JOIN street_type AS st ON s.id_street_type=st.id_street_type
LEFT JOIN building AS b ON d.id_building=b.id_building
LEFT JOIN entrance AS e ON d.id_entrance=e.id_entrance;

И аксес на него материться что запрос не верный... Где и что я упустил в синтаксисе акссеса?
Ответ:
Владимир Саныч
СергейЯ
Следите за скобками!

А что не так было со скобками? (a+b)+c или a+(b+c) - какая разница?

Отвечаю сам себе:
Таблица2 LEFT JOIN Таблица3 ON Таблица3.[1]=Таблица1.[1]
Вопрос: странная ошибка с LEFT JOIN

Ребят, что ему не нравится? Никак не пойму. Все таблицы и поля существуют!
SELECT * FROM prt_catalog_cat a LEFT JOIN prt_catalog_dates b ON a.EventID = b.EventID WHERE b.EventDate >= NOW() AND a.Name LIKE "цв%" and a.Active=1;


Ошибка:
Error in query (1054): Unknown column 'a.Name' in 'where clause'
Ответ: darkersoul,

Очевидно, в таблице prt_catalog_cat нет поля Name.

И, кстати, по факту ваш запрос будет работать как просто JOIN, а не как LEFT JOIN.
Вопрос: left join для двух полей

Что-то никак не разберусь. Есть
tbl1
dt_acc, kt_acc, sum

tbl2
acc, name

Надо чтобы на выходе было

dt_acc, name, kt_acc, name, sum
123, first acc, 321, second acc, 1000

пишу
select tbl1.dt_acc, tbl2.name, tbl1.dt_acc, tbl2.name, tbl1.sum from tbl1 left join on tbl1.dt_acc = tbl2.acc or tbl1.kt_acc =tbl2.acc


и мне соответственно в оба name пишет одно и тоже, а как сделать чтобы он писал соответствующие имена счетов для acc, а если нет названия счета в tbl2 ставил null
Ответ: Badhabit,

сели и поехали... в пути научимся :)

что-то вроде

select 
[operations].data, 
[dt].dt_account, 
[dt].TNAME, 
[kt].kt_account, 
[kt].TNAME, 
[operations].sum 
from operations
left join accounts [dt] on [dt].acc  = [operations].dt_acc 
left join accounts [kt] on [kt].acc  = [operations].kt_acc 


автор
[Debit] и [Credit] это типа виртуальных таблиц? или как правильно называется?

алиас, кличка :)
Вопрос: Условие в Left Join VS Where

Имеем запрос:
Select count(*),
                    NVL(sum(case when NVL(s.serno, 0) > 0 then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('S2NT') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('SUCC', 'FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') = 'SUCC' and s.authserno > 0 then 1 else 0 end),0)
               from ctransactions t
               left outer join interfacerecordstatus s on t.serno = s.rowserno and s.partitionkey = t.partitionkey and s.recordtype = 'TRXN' and s.systemname = 'online' and s.systemtype = 'O'
              where t.batchserno = 321356
                and t.stgeneral = 'POST'
                


Он аццки тормозит, независимо от того хинтую я индексы или нет. Но вот если перенести часть условия в Where то он начинает летать хотьв пане запроса идет Full Scan по interfacerecordstatus
Что за ерунда? Надо статистику индексов пересобрать? Таблицы партицированные.

Этот летает:
Select count(*),
                    NVL(sum(case when NVL(s.serno, 0) > 0 then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('S2NT') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('SUCC', 'FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') = 'SUCC' and s.authserno > 0 then 1 else 0 end),0)
               from ctransactions t
               left outer join interfacerecordstatus s on t.serno = s.rowserno and s.partitionkey = t.partitionkey
              where t.batchserno = 321356
                and t.stgeneral = 'POST'
                and s.recordtype = 'TRXN' and s.systemname = 'online' and s.systemtype = 'O'
                
Ответ:
SY

В oбщем случае это не эквивалентно:


Ты можешь использовать NVL если поля s.recordtype, s.systemname и s.systemtype определены как NOT NULL:

Select count(*),
                    NVL(sum(case when NVL(s.serno, 0) > 0 then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('S2NT') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') in ('SUCC', 'FAIL') then 1 else 0 end),0),
                    NVL(sum(case when NVL(s.status, 'XXXX') = 'SUCC' and s.authserno > 0 then 1 else 0 end),0)
               from ctransactions t
               left outer join interfacerecordstatus s on t.serno = s.rowserno and s.partitionkey = t.partitionkey
              where t.batchserno = 321356
                and t.stgeneral = 'POST'
                and nvl(s.recordtype,'TRXN') = 'TRXN' and nvl(s.systemname,'online') = 'online' and nvl(s.systemtype,'O') = 'O'


SY.
Вопрос: LEFT JOIN таблицы (по минимальной, максимальной дате)

Есть две таблицы
Первая
Номер документа (id), Дата создания (_date)

Вторая
Номер документа (id), Дата изменения (change_date)

Можно ли LEFT JOIN вторую к первой дважды чтобы получить два новых параметра на выходе
Первое и последнее изменение
Ответ:
Николай Жуков
как в LEFT JOIN использовать MIN либо MAX

Типа
SELECT f.id, f._date, q.dmin, q.dmax
FROM first_table f
LEFT JOIN ( SELECT s.id, MIN(s.change_date) dmin, MAX(s.change_date) dmax
            FROM second_table s
            GROUP BY s.id
          ) q ON q.id = f.id
Вопрос: LEFT JOIN по нескольким полям

Добрый день всем!

Подскажите, почему запрос связывает таблицы по каждому условию в отдельности
и в результате получается декартово произведение (по полям, указанным в ON)?

SELECT * FROM
	(select * from T where F0 = 1) a
LEFT JOIN
	(select * from T where F0 = 0) b
ON 
	a.F1 = b.F1
	and a.F2 = b.F2
	and a.F3 = b.F3
Ответ: Да, Вы правы. Не учел, что LEFT JOIN дублирует запись левой таблицы, если ей соответствует несколько записей в правой.
Вопрос: Left Join и условие по правой таблице

Дано:
Таблица оборудования, в ней поля: Id, Название.
Таблица выработки, при создании единицы продукции в нее помещается новая запись с Id_станка на котором собрали.

Я хочу выбрать распределение выработки по станкам, в т. ч. и тем станкам, по которым выработка отсутствует.

Т. е. если есть станок 1 с выр-кой 10, станок 2 с выр-кой 15 и станок 3 с выр-кой 0 я делаю запрос

Select Оборудование.Id, Оборудование.Название, Count(Выработка.Id) From Оборудование
Left Join Выработка on Оборудование.Id=Выработка.Id_Оборудование
Group By  Оборудование.Id, Оборудование.Название


Получаю, как и написано в инструкции к Join, результат вида:
1 "Станок 1" 10
2 "Станок 2" 15
3 "Станок 3" 0

Но если я добавлю к правой таблице условие, например

Select Оборудование.Id, Оборудование.Название, Count(Выработка.Id) From Оборудование
Left Join Выработка on Оборудование.Id=Выработка.Id_Оборудование
Where Выработка.Время>'2018.01.01'
Group By  Оборудование.Id, Оборудование.Название


То я уже получаю результат вида:
1 "Станок 1" 10
2 "Станок 2" 15

Меня это не устраивает. Как обойти?
Ответ:
iap
Beltar
Count(*) и Count(Id) тоже должны быть эквивалентны, если Id является первичным ключом, а значит не может быть NULL по определению.
В таблице не может.
А в запросе ещё как может!
Пример вы сами привели своим запросом с LEFT JOIN
Может быть, вы считаете, что COUNT(ПолеТаблицы) считает какие-то там поля таблицы?
Однако, COUNT() всегда считает количество строк!