在sql

问题描述:

的组表达式中使用“where”我需要提出这样的请求:选择包含字母i的城市列表并且拥有适当数量的员工。此外,我需要注意的是,某个城市可能有0名员工,而对于某些员工而言,债务可能为空。在sql

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员工(例如,此请求不显示城市rivne其中有0名员工),对于某些员工而言,DEBT可能为空。

我用甲骨文与蟾蜍。

预期结果

city numb 
kiev 1 
rivne 0 
lviv 3 

照顾标准移动where前分组。要允许不存在员工或无债务,请使用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是员工的主键)。 但是,如果没有员工,这将不会返回部门,并且CITY将不会与部门的城市匹配%i%或者empl.DEBT从一开始就为空。

为了解决这个问题,我们可以用union来扩展第一个查询,这些union都是为了检索没有部门的员工而设计的。但有一个问题:我们是否只需要无部门的员工,或者我们考虑的还是员工不在没有任何分部名称的城市工作。我选择了第二种可能性。

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 

这个查询将匹配城市数的员工,不匹配的城市和那些没有部门的人。

+0

这样的请求后,我得到rivne到城市名单,但麻木为1,应该是0. – khris 2012-08-07 07:34:49

+0

@khris请再次检查我的答案。我改变了数(*)部分。 – 2012-08-07 07:35:51

+0

如果我要显示也没有部门的员工数量(如empl中的45),如何修改请求? – khris 2012-08-07 07:53:07

这样做:

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; 

WHERE至上GROUP BY之前

+0

这与OP的代码发布有什么不同? – lamwaiman1988 2012-08-07 07:25:48

+0

@ lamwaiman1988一小时前,它被颠倒了。 GROUP BY,然后WHERE。看到OP的编辑 – 2012-08-07 08:24:42

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