dongmi4809 2014-11-26 14:42
浏览 58
已采纳

在SQL QUERY不一致的WHERE子句中将AND IN与AND连接

Here's my debacle. If I run:

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

I get

 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

When I run:

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

I get

 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

Good so far, lets try this:

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

I get:

 PNUMBER   NUM_EMPS     THOURS      TCOST
---------- ---------- ---------- ----------
     1          1       32.5      487.5
     2          1        7.5      112.5

Also good, but when I try this (all i did was add another Not in the Where clause):

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

I get "no rows selected"! How? There should still be 2 employees that are not managers or supervisors for pnumber 1. Please help? Thanks,

EDIT

Here is the result with just one 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
  • 写回答

2条回答 默认 最新

  • dongqiu8375 2014-11-26 16:18
    关注

    NOT IN returns no rows where any value is NULL. So:

    WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE)
    

    will filter everything out if even one row as SUPERSSN as NULL. Here are two ways to fix it:

    WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE where SUPERSSN is not null)
    

    or:

    WHERE NOT EXISTS (select 1 from EMPLOYEE e where e.SUPERSSN = ssn)
    

    (You might need an alias on the ssn, but I have no idea what table it comes from.) In other words, the semantics of NOT EXISTS and NOT IN are different when there is a NULL value. NOT EXISTS (in my opinion) has the more intuitive behavior.

    Now, why does this never return true if one of the values is NULL?

    WHERE ssn NOT IN (select SUPERSSN from EMPLOYEE)
    

    If ssn is in the list of SUPERSSN, then it returns false. That is easy. If ssn is not in the list and none of the values are NULL, then it returns true. That is easy.

    If ssn is in the list and one of the values of SUPERSSN is NULL, then there's a conundrum. Is ssn equal to the NULL value or not. Well, neither. Comparisons to NULL return NULL. And, NULL is treated as "not true" in WHERE clauses. In short, if SUPERSSN has a NULL value, the expression can only return false or NULL -- and everything gets filtered out.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么