在sql中的组表达式中使用“where”

时间:2012-08-07 07:04:47

标签: sql database oracle

我需要提出这样的要求:选择包含字母i的城市列表,并拥有适当数量的员工。此外,我需要注意一些城市可能有0名员工,而对于某些员工领域,DEBT可能为空。

depart

debt    city
-------------
43      odesa
23      kiev
79      lviv
78      lviv
12      rivne

empl

ide     fn      ln      debt
----------------------------
3421    jed     trt     43
354     jed     res     43
43      ged     hjkhg   79
73      ghghg   gfgf    79
456     jkl     gdfg    
532     kkhg    vjv     23
45      ki      vt      
243     ki      vt      78

我写了这个查询:

select depart.CITY, count (*) as numb 
from depart 
   inner join empl on  empl.DEBT=depart.DEBT
where depart.CITY like '%i%'
group by depart.CITY;

但是我不知道如何关注某个城市可能有0名员工(例如此请求不会显示拥有0名员工的城市rivne)以及某些员工字段DEBT可能为空。

我将oracle与toad一起使用。

预期结果

city    numb
kiev    1
rivne   0
lviv    3

3 个答案:

答案 0 :(得分:3)

这样做:

select depart.CITY, count (*) as numb 
from depart inner join empl on empl.DEBT=depart.DEBT
where depart.CITY like '%i%'
group by depart.CITY;

在GROUP BY

之前首先出现

答案 1 :(得分:3)

WHERE子句出现在GROUP BY子句之前 像这样:

SELECT depart.CITY, COUNT (*) AS numb 
FROM depart INNER JOIN empl ON empl.DEBT=depart.DEBT
WHERE depart.CITY LIKE '%i%'    
GROUP BY depart.CITY;

See this fiddle for WHERE clause.

或者你也可以使用HAVING条款
像这样:

SELECT depart.CITY, COUNT (*) AS numb 
FROM depart INNER JOIN empl ON empl.DEBT=depart.DEBT
GROUP BY depart.CITY
HAVING depart.CITY LIKE '%i%';

See this fiddle for HAVING clause.

更有可能使用HAVING条款 See this link for more details

答案 2 :(得分:2)

在分组之前处理标准移动where。要允许不存在的员工或null DEBT,请使用left outer join

select depart.CITY, count (empl.DEBT) as numb 
  from depart 
  left join empl 
    on empl.DEBT = depart.DEBT
 where depart.CITY like '%i%'
 group by depart.CITY;

要按部门分组所有员工,您可以撤销外部联接:

select depart.CITY, count (empl.ide) as numb 
  from empl  
  left join depart
    on empl.DEBT = depart.DEBT
 -- Note: condition is now part of a join. This is required
 --       as part of outer join because otherwise left hand
 --       table row would be filtered out.
   and depart.CITY like '%i%'
 group by depart.CITY;

(据推测ide是员工的主要关键)。 但是这不会返回没有员工的部门,而且当部门的城市不匹配%i%或者empl.DEBT从一开始就是空的时候,CITY将为空。

要解决这个问题,可以使用union来扩展第一个查询,这个查询旨在检索没有部门的员工。但是有一个问题:我们是否只想要无部门的员工,或者我们认为或员工不在一个名字中包含i无部门的城市工作。我选择了第二种可能性。

select depart.CITY, count (empl.DEBT) as numb 
  from depart 
  left join empl 
    on empl.DEBT = depart.DEBT
 where depart.CITY like '%i%'
 group by depart.CITY;
select '(unknown or unmatched city)', count (*) as numb
  from empl
  left join depart
    on empl.DEBT = depart.DEBT
   and depart.CITY like '%i%'
 where depart.DEBT is null;

如果您需要区分没有部门的员工和在不包含i的城市工作的员工,您可以使用case

select case when depart.CITY like '%i%'
            then depart.CITY
            when depart.DEBT is null
            then '(No department)'
            else '(City does not match %i%)'
        end as CITY,
       count (*) as numb
  from empl
  left join depart
    on empl.DEBT = depart.DEBT
 group by 
       case when depart.CITY like '%i%'
            then depart.CITY
            when depart.DEBT is null
            then '(No department)'
            else '(City does not match %i%)'
        end

此查询将统计来自匹配城市,不匹配城市和没有部门的员工。