2010-02-09 5 views
2

У меня есть три таблицы (ради аргумента), индивидуальные, электронные письма и атрибуты. 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 = '[email protected]' 
and a.attr_code_Ref = 4119 
group by e.individual_ref 

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

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 = '[email protected]' 
group by e.individual_REf 

возвращает один ряд с individual_Ref и подсчет 0

Я не предлагаю SQL сломана более, что мое понимание .. поэтому я думаю, «каково мое замешательство?» это вопрос.

+0

+1 для получения людей, чтобы рассмотреть эффект предложение WHERE в контексте JOIN –

+0

благодарит за ответы! –

ответ

1

При преобразовании подзапроса в 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 = '[email protected]' 
GROUP BY 
     e.individual_ref 
+0

Я думаю, это очевидно, что я самоучка и что немного знаний - опасная вещь :-) Спасибо за ваш ответ - теперь все немного ясно ... –

3

следующая часть заставляет присоединиться изменить:

from email e left join attribute a on e.individual_Ref = a.individual_ref 
where e.email_Address = '[email protected]' 
and a.attr_code_Ref = 4119 

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

Вы должны были бы позволить a.attr_code_ref = 4199 or a.attr_code_ref is null

+0

Короче: isnull (a.attr_code_ref, 0) = 4199 – momobo

+0

Определенно короче, но мне интересно (проверено havnt), делает ли это сохранение SARGable или нет. Функция, применяемая к тестируемому полю, имеет тенденцию нарушать его. – Andrew

+1

'= null' никогда не будет истинным; попробуйте 'is null' – Andomar

1

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

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 = '[email protected]' 
and (a.attr_code_Ref = 4119 or a.individual_ref is null) 
group by e.individual_ref 

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

0

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^