在where子句中过滤右连接数据

时间:2012-02-08 13:28:28

标签: sql sql-server sql-server-2000

我有一个简单的表结构,其中每个项目行都有一个状态。我正在寻找的是查询每个状态并计算使用该状态的项目数。可能不会使用所有状态,因此我需要考虑空值和零计数。

我的表格结构如下:

Table: Items
Id, State_id, Text, Status

Table: States
State_id, Name

这就是我所拥有的:

SELECT   statealias1_.State_id as y0_,
         count(this_.Id)       as y1_
FROM     Items this_
         right join States statealias1_
           on this_.State_id = statealias1_.State_id
WHERE    (not (statealias1_.State_id in (5, 6, 7, 8)) 
            or statealias1_.State_id is null)
         and (this_.Status = 'InProgress' 
            or this_.Status is null)
GROUP BY statealias1_.State_id;

此查询适用于包含所有状态(有8个状态,我排除了后半部分)。我不知道为什么这不会返回我所有状态的计数而不管空值,因为我似乎包括空值。

4 个答案:

答案 0 :(得分:2)

select i.State_id as y0_, count(i.Id) as y1_
from Items i
left join States s on i.State_id = s.State_Id and i.Status = 'InProgress'
group by i.State_id

答案 1 :(得分:1)

我会反过来......从你的“状态”条目开始,然后LEFT JOIN到你希望包含的预聚合结果集

select
      S.State_ID,
      COALESCE( PreAgg.ICount, 0 ) as StateCount
   from
      States S
         LEFT JOIN ( select I.State_ID, count(*) as ICount
                        from Items I
                        where NOT I.State_ID IN( 5, 6, 7, 8 )
                          AND I.Status = 'InProgress'
                        group by I.State_ID ) PreAgg
            on S.State_ID = PreAgg.State_ID

答案 2 :(得分:1)

你很接近,但是从我通常看到它的方式来看,你已经倒退了。

SELECT s.State_id, COUNT(i.Id)
FROM States AS s
LEFT OUTER JOIN Items AS i ON i.State_id = s.State_id
WHERE ...
GROUP BY s.State_id

答案 3 :(得分:1)

我认为你的SQL是正确的,但你的where条件可能存在逻辑错误。

你有:

WHERE    (
             NOT (statealias1_.State_id in (5, 6, 7, 8)) 
             OR  statealias1_.State_id is null
)
AND      (this_.Status = 'InProgress' or this_.Status is null)

你的意思是:

WHERE    NOT (
                 statealias1_.State_id in (5, 6, 7, 8) 
                 OR statealias1_.State_id is null
         )
         AND ( this_.Status = 'InProgress' or this_.Status is null )