这是我的崩溃。如果我跑:
SELECT pnumber, count(distinct ssn) as num_emps,nvl(sum(hours),0) as thours, nvl(sum(hours*salary/2000),0) as tcost
FROM project
LEFT JOIN (works_on join (employee
LEFT JOIN Department on DNO=DNUMBER) on essn=ssn)
ON pnumber=pno
GROUP BY pnumber
ORDER BY pnumber
我得到了
PNUMBER NUM_EMPS THOURS TCOST
---------- ---------- ---------- ----------
1 4 67.5 1027.5
2 3 37.5 562.5
3 2 50 960
10 3 55 762.5
20 3 25 522.5
30 4 60 967.5
40 0 0 0
50 0 0 0
60 0 0 0
当我跑步时:
SELECT pnumber, count(distinct ssn) as num_emps,nvl(sum(hours),0) as thours, nvl(sum(hours*salary/2000),0) as tcost
FROM project
LEFT JOIN (works_on join (employee
LEFT JOIN Department on DNO=DNUMBER) on essn=ssn)
ON pnumber=pno
WHERE ssn IN (select MGRSSN from DEPARTMENT)
GROUP BY pnumber
ORDER BY pnumber
我得到了
PNUMBER NUM_EMPS THOURS TCOST
---------- ---------- ---------- ----------
1 1 5 100
2 1 10 200
3 1 10 200
10 1 10 200
20 3 25 522.5
30 2 25 530
到目前为止,让我们试试这个:
SELECT pnumber, count(distinct ssn) as num_emps,nvl(sum(hours),0) as thours, nvl(sum(hours*salary/2000),0) as tcost
FROM project
LEFT JOIN (works_on join (employee
LEFT JOIN Department on DNO=DNUMBER) on essn=ssn)
ON pnumber=pno
WHERE ssn IN (select SUPERSSN from EMPLOYEE) AND ssn NOT IN (select MGRSSN from DEPARTMENT)
GROUP BY pnumber
ORDER BY pnumber
我明白了:
PNUMBER NUM_EMPS THOURS TCOST
---------- ---------- ---------- ----------
1 1 32.5 487.5
2 1 7.5 112.5
也很好,但是当我尝试这个时(我所做的只是在Where子句中添加另一个Not):
SELECT pnumber, count(distinct ssn) as num_emps,nvl(sum(hours),0) as thours, nvl(sum(hours*salary/2000),0) as tcost
FROM project
LEFT JOIN (works_on join (employee
LEFT JOIN Department on DNO=DNUMBER) on essn=ssn)
ON pnumber=pno
WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE) AND ssn NOT IN (select MGRSSN from DEPARTMENT)
GROUP BY pnumber
ORDER BY pnumber
我得到“没有选择行”!怎么样?还应该有2名员工不是第1号的经理或主管。请帮忙吗?谢谢,
修改
这是只有一个NOT IN的结果:
SQL> SELECT pnumber, count(distinct ssn) as num_emps,nvl(sum(hours),0) as thours, nvl(sum(hours*salary/2000),0) as tcost
2 FROM project
3 LEFT JOIN (works_on join (employee
4 LEFT JOIN Department on DNO=DNUMBER) on essn=ssn)
5 ON pnumber=pno
6 WHERE ssn NOT IN (select MGRSSN from DEPARTMENT)
7 GROUP BY pnumber
8 ORDER BY pnumber;
PNUMBER NUM_EMPS THOURS TCOST
---------- ---------- ---------- ----------
1 3 62.5 927.5
2 2 27.5 362.5
3 1 40 760
10 2 45 562.5
30 2 35 437.5
答案 0 :(得分:1)
NOT IN
不会返回任何值为NULL
的行。所以:
WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE)
如果SUPERSSN
行为NULL
,则会过滤所有内容。以下是两种解决方法:
WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE where SUPERSSN is not null)
或:
WHERE NOT EXISTS (select 1 from EMPLOYEE e where e.SUPERSSN = ssn)
(您可能需要ssn
上的别名,但我不知道它来自哪个表。)换句话说,NOT EXISTS
和NOT IN
的语义不同有一个NULL
值。 NOT EXISTS
(在我看来)具有更直观的行为。
现在,如果其中一个值是NULL
?
WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE)
如果ssn
列在SUPERSSN
中,则返回false。这很容易。如果ssn
不在列表中且,则没有值为NULL
,则返回true。这很容易。
如果ssn
位于列表中且其中一个SUPERSSN
值为NULL
,那么就会出现一个难题。 ssn
是否等于NULL
值。好吧,既不。与NULL
的比较返回NULL
。并且,NULL
在WHERE
子句中被视为“不正确”。简而言之,如果SUPERSSN
的值为NULL
,则表达式只能返回false或NULL
- 并且所有内容都会被过滤掉。
答案 1 :(得分:0)
尝试:
WHES ssn NOT IN(从EMPLOYEE联盟中选择SUPERSSN从部门选择MGRSSN)