2016-04-21 7 views
3

Я изучаю экзамен SQL Server, и у меня возникли эти вопросы, на которые я ответил неправильно, но я не понимаю, почему правильные ответы правильные и как вы их получите.Неверный прогноз результата SQL Server

nr naam aantal chef 
1 Anouk 14 2 
2 Hans 14 NULL 
3 Ali 13 5 
4 Kees 12 5 
5 Ben 3 2 

nr soort stad chef 
1 cursus DenHaag 2 
2 cursus Amsterdam NULL 
3 congres NewYork 5 
4 lezing Utrecht 5 

nr werknemer reis aantal datum bedrag 
01 1   4 8 17-04-2013 420,56 
02 3   3 5 05-04-2013 825,80 
03 1   1 5 10-04-2013 140,00 
04 null  2 2 10-04-2013 156,75 
05 4   4 8 17-04-2013 328,90 
06 5   3 5 05-04-2013 560,45 

В 2 вопроса:

а.

SELECT naam 
FROM werknemer 
WHERE nr NOT IN (SELECT werknemer 
      FROM declaratie); 

b.

SELECT naam, COUNT(*) 
FROM werknemer w LEFT OUTER JOIN declaratie d ON w.nr = d.werknemer 
GROUP BY naam; 

Мои ответы:

a: Hans 
b: naam count(*) 
Anouk 2 
Hans 0 
Ali  1 
Kees 1 
Ben  1 

Но правильные ответы:

a: none 
b: naam count(*) 
Anouk 2 
Hans 1 
Ali  1 
Kees 1 
Ben  1 

Может кто-нибудь объяснить мне, что я, вероятно, пропустил?

ответ

4

а), потому что выполнение любого вида NOT IN (1,NULL,3,4,5) возвращает набор NULL набор результатов, поскольку SQL не может сказать ли данная величина не равна NULL и, таким образом, эффективно возвращает «Я не знаю». Это отличное объяснение этого on Stack Overflow.

Причина b) неверна в том, что вы находитесь LEFT JOIN от werknemer. Таким образом возвращаются все строки из werknemer, включая Hans. COUNT(*) возвращает количество строк, относящихся к этому лицу, так Hans возвращает 1. Если бы вы COUNT(d.werknemer) тогда Hans будет 0, так как все declaratie колонны будет NULL для Hans, потому что JOIN предикат не будет соблюден.

+0

Теперь я понимаю. Я запустил запрос с SQL-сервера без NOT, и он выводит все имена, кроме Hans, но вы говорите, что это (IN (1, NULL, 3,4,5)) приводит к набору результатов NULL? –

+1

Я уточнил свою точку зрения а) и предоставил ссылку, которая очень четко отвечает на ваш вопрос. – strickt01

1

Очень вероятно, что вы пропустите то, что нет никакого способа сравнить NULL и INT, используя '='. Это делает ваш результат другим, вы считаете, что сравнение 2 (Ганс) с NULL из declaratie вернет false. Вы должны попытаться запустить этот запрос, чтобы увидеть, что я имею в виду:

if 1=null or 1=1 print 'true' else print 'false' 
if 1=null and 1=1 print 'true' else print 'false' 
1

Хорошо, так что это не так, потому что нуль. Вы не можете использовать в (1,2,3, null, 5) Это вернет нулевое решение, и вы его не получите. Для b, поскольку вы используете левое соединение, это означает, что вы получаете всю исходную таблицу со всеми значениями второго. Таким образом, это означает, что вы получаете строку для hans, но все нули в левой части, потому что нет совпадения (но вы все еще считаете ее строкой)