SQL Joins: в, вне, встряхните все это о - PullRequest
1 голос
/ 05 ноября 2010

Я выполняю следующий sql, чтобы вернуть данные, в которых есть совпадение как dob, так и адреса в таблицах 1 и 2.

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate
group by table1.dob, table1.address
order by table1.dob, table1.address

Однако теперь я хочу вернуть данные из таблицы 1, когда естьнет совпадений в таблице 2 и только эти данные, я подумал, что простое изменение внутреннего соединения на левое внешнее будет выполнять то, что мне нужно, это не так.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 05 ноября 2010

Если в соединении нет совпадений, поля из второй таблицы имеют значение ПУСТО (NULL), поэтому необходимо проверить значение NULL в таблице2.Предполагая, что dob не равен NULL в таблице 2, это должно решить вашу проблему:

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
left outer join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate and table2.dob is null
group by table1.dob, table1.address
order by table1.dob, table1.address
2 голосов
/ 05 ноября 2010

В этом случае это не объединение, вам следует использовать функцию НЕ СУЩЕСТВУЕТ .

1 голос
/ 05 ноября 2010

По моему мнению, LEFT JOIN намного чище, и вы должны пойти на это, если нет большой разницы между производительностью LEFT JOIN и NOT EXISTS.@JNK сказал: «СУЩЕСТВУЮТ, а НЕ СУЩЕСТВУЮТ, как правило, быстрее, чем объединения или другие операторы, такие как IN, потому что они замыкают накоротко - при первом попадании они переходят к следующей записи», но я понимаю, что NOT EXISTS и NOT INкак правило, дорого, поскольку сервер sql должен пройти через все записи в таблице поиска, чтобы убедиться, что запись на самом деле НЕ СУЩЕСТВУЕТ, поэтому я не знаю, как будет работать короткое замыкание

0 голосов
/ 05 ноября 2010

Вы также можете использовать ключевое слово EXCEPT здесь.

select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
where table1.dob > @myDate
EXCEPT
select table1.dob
, table1.address
, sum(case when person_status in ('A','B','C') then 1 else 0 end) as 'ABC_count'
, sum(case when person_status in ('D','E') then 1 else 0 end) as 'DE_Count'
, sum(case when person_status in ('F','G') then 1 else 0 end) as 'FG_Count' 
from table1
inner join table2
on (table1.dob = table2.dob and table1.address = table2.address)
where table1.dob > @myDate

Это даст вам все записи в первом запросе, которых нет во втором запросе.

...