使用CASE在结果中获取表的零值

时间:2013-05-16 09:23:22

标签: sql oracle oracle10g

我有下表:

      State           Soccer players     Tennis players
        CT                   0                 0        
        IL                   5                 10
        IN                   3                  8
        MI                  12                 14
        OH                   8                  9
        AR                   2                  2
        KS                   14                 16
        AL                   8                  7
        CA                   1                  13 
        NV                   2                   3

我想形成一个如下所示的输出表

Region         Total_players
East               0
MidWest            60
SouthWest          34
West               29
SouthEast          0

我试图在东部地区获得结果,但没有任何球员。但是,在我的结果集中,我没有得到“东方”。

我尝试了以下不会产生“东部”区域的查询。

select CASE 
        WHEN STATE IN ('AL','FL','GA','KY','LA','MS','NC','SC','TN') THEN 'SE'
        WHEN STATE IN ('IL','IN','MI','OH','WI') THEN 'MW'
            WHEN STATE IN ('AR','KS','MO','OK','TX') THEN 'SW'
            WHEN STATE IN ('CT') THEN 'E'
            WHEN STATE IN ('CA','NV') THEN 'W'
            ELSE 'Error'
        END AS Region,
        COUNT(*) as Total,
        from players WHERE TRUNC(t.date) >= to_char(to_date(?,'DY MON DD HH24:MI:SS YYYY'),'DD-MON-YYYY') 
                and TRUNC(t.date) <= to_char(to_date(?,'DY MON DD HH24:MI:SS YYYY'),'DD-MON-YYYY')
        GROUP BY ROLLUP(Region) ORDER BY Region

3 个答案:

答案 0 :(得分:1)

如果您在播放器表中缺少东区域,那么您必须从另一个表中获取区域列表,并使用查询结果离开连接。 如果您不想创建表(例如一次性报告),可以使用union和dual构建表,例如:

select region.long_name, region.short_name 
from (
    select 'SouthEast' long_name, 'SE' short_name from dual
    union all
    select 'MidWest' long_name, 'MW' short_name from dual
    union all
    select 'SouthWest' long_name, 'SW' short_name from dual
    union all
    select 'East' long_name, 'E' short_name from dual
    union all
    select 'West' long_name, 'W' short_name from dual
) region

创建查询时,您可以选择此区域中的所有行(虚拟或真实表),并使用每个区域中的玩家总数左键连接,例如:

select 
    region.long_name "Region",
    sum (player.total_players) "Total players"
from (
    select 'SouthEast' long_name, 'SE' short_name from dual
    union all
    select 'MidWest' long_name, 'MW' short_name from dual
    union all
    select 'SouthWest' long_name, 'SW' short_name from dual
    union all
    select 'East' long_name, 'E' short_name from dual
    union all
    select 'West' long_name, 'W' short_name from dual
) region
left join (
    select CASE 
        WHEN STATE IN ('AL','FL','GA','KY','LA','MS','NC','SC','TN') THEN 'SE'
        WHEN STATE IN ('IL','IN','MI','OH','WI') THEN 'MW'
        WHEN STATE IN ('AR','KS','MO','OK','TX') THEN 'SW'
        WHEN STATE IN ('CT') THEN 'E'
        WHEN STATE IN ('CA','NV') THEN 'W'
        ELSE 'Error'
    END region_short_name,
    (players.soccer_players + players.tennis_players) total_players
    from players 
    WHERE TRUNC(t.date) >= to_char(to_date(?,'DY MON DD HH24:MI:SS YYYY'),'DD-MON-YYYY') 
    and TRUNC(t.date) <= to_char(to_date(?,'DY MON DD HH24:MI:SS YYYY'),'DD-MON-YYYY')
) player on player.region_short_name = region.short_name
group by region.long_name

答案 1 :(得分:0)

快速回答:

你评论说东区肯定在你的表中有一行,这意味着它没有显示的简单原因是你的WHERE子句。删除它,该区域应重新出现。只有你可以判断该条款是否正确。


根据您对此答案的评论,您需要拥有一个地区和州的表格,或者您需要创建一个;无关紧要。

首先,您需要一个区域唯一的表,这是您在区域级别存储所有信息的地方

create table regions (
    region varchar2(10)
  , ...
  , constraint pk_regions primary key (region)
    ); 

接下来是状态上的唯一一个,这是您在州一级存储所有信息的地方

create table states (
    state  varchar2(20)
  , ...
  , constraint pk_states primary key (state)
    ); 

然后,您应该使用您的信息填充这两个,并创建一个连接在两者之间的第三个表。

create table region_states (
    region varchar2(10)
  , state  varchar2(20)
  , constraint pk_region_states primary key (region, state)
  , constraint fk_rs_regions foreign key (region) references regions (region)
  , constraint fx_rs_states foreign key (state) references states (state)
    ); 

接下来,你应该从你自己的STATES表中获得一个外键。这是首选但可能会影响您当前的表格,因此请小心移动。

alter table your_table
  add constraint fk_players 
      foreign key (state)
      references states (state)

最后,您加入REGION_STATES以获取信息。

select rs.region, sum(p.soccer_players + p.tennis_players) as total_players
  from players p
  join region_states rs
    on p.state = rs.state
 group by rs.region

请注意,我还没有使用过SUM()而不是COUNT()......你想要玩家的总数,而且由于数据已经在州一级汇总了,因此COUNT()会计算州的数量,而不是球员数量。

答案 2 :(得分:0)

它将提供所需的输出。无法理解where子句中的日期,因为它不在表中。

    select CASE 
    WHEN STATE IN ('AL','FL','GA','KY','LA','MS','NC','SC','TN') THEN 'SE'
    WHEN STATE IN ('IL','IN','MI','OH','WI') THEN 'MW'
        WHEN STATE IN ('AR','KS','MO','OK','TX') THEN 'SW'
        WHEN STATE IN ('CT') THEN 'E'
        WHEN STATE IN ('CA','NV') THEN 'W'
        ELSE 'Error'
    END AS Region,
    sum(soccer_players + tennis_players) as total_players,
    from players
    group by region