Не понимаю, почему эти два запроса дают разные результаты - PullRequest
2 голосов
/ 09 февраля 2010

У меня есть три таблицы (ради аргумента) индивидуальные, адрес электронной почты и атрибут. individual_Ref внешний ключ, который связывает индивида с электронной почтой и атрибутом.

Нет необходимости, чтобы конкретное лицо было представлено в таблице атрибутов, поскольку у него, возможно, никогда не было добавлено атрибута, и они могут появляться более одного раза, если у них более одного атрибута.

Я хочу получить список отдельных ссылок и количество определенных атрибутов для них. Но нужно искать по адресу электронной почты, так как физическим лицам разрешено делиться адресами электронной почты (не заводите меня) ...

Мой первый удар был

select e.individual_ref, count(a.attr_Code_ref)
from email e left join attribute a on e.individual_Ref = a.individual_ref
where e.email_Address = 'example.email@adomain.net'
and a.attr_code_Ref = 4119 
group by e.individual_ref

использование левого соединения, чтобы убедиться, что я получаю индивидуальный реф по электронной почте, если таковой существует, и чтобы получить результат, если есть индивидуальный реф в электронном письме, но не в атрибуте. Или так я думал, так как это не возвращает строк, но ...

select e.individual_ref, 
(select count(a.attr_Code_ref) from attribute a where a.attr_code_Ref = 4119 and a.individual_ref = e.individual_ref)
from email e
where e.email_Address = 'example.email@adomain.net'
group by e.individual_REf

возвращает одну строку с Individual_Ref и счетчиком 0

Я не утверждаю, что SQL сломан больше, чем мое понимание ... поэтому я думаю, "в чем моя путаница?" это вопрос.

Ответы [ 4 ]

3 голосов
/ 09 февраля 2010

следующая часть вызывает изменение объединения:

from email e left join attribute a on e.individual_Ref = a.individual_ref 
where e.email_Address = 'example.email@adomain.net' 
and a.attr_code_Ref = 4119  

Поместив предложение where в код a.attr_code, вы превратили левое соединение во внутреннее соединение, например, там, где нет записи атрибута, возвращается null, что не соответствует предложению where. (поскольку a.attr_code_ref не может быть 4119, записи не было.)

Вам нужно разрешить a.attr_code_ref = 4199 or a.attr_code_ref is null

1 голос
/ 09 февраля 2010

При преобразовании подзапроса в LEFT JOIN коррелированные условия WHERE в подзапросе переходят в предложение ON объединения, а не в предложение WHERE:

SELECT  e.individual_ref, count(a.attr_Code_ref)
FROM    email e
LEFT JOIN
        attribute a
ON      a.individual_ref = e.individual_Ref
        AND a.attr_code_Ref = 4119 
WHERE   e.email_Address = 'example.email@adomain.net'
GROUP BY
        e.individual_ref
1 голос
/ 09 февраля 2010

Изменить первый в:

select e.individual_ref, count(a.attr_Code_ref)
from email e left join attribute a on e.individual_Ref = a.individual_ref
where e.email_Address = 'example.email@adomain.net'
and (a.attr_code_Ref = 4119 or a.individual_ref is null)
group by e.individual_ref

и вы получите те же результаты

0 голосов
/ 09 февраля 2010

В первом запросе вы объединяете две таблицы и ищете все строки, соответствующие обоим условиям - их нет.

Во втором запросе вы получаете строки из первой таблицы, соответствующие условию электронной почты (есть одна), и количество строк, соответствующих вашему второму условию из другой таблицы, их 0 .

...