SQL group by和每个组的位置

时间:2016-04-08 03:00:34

标签: sql sql-server database

我有一个包含sourceId(guid),state(1:Deactivated,2:Activated,3:Dead),modifiedDate等列的表。

我正在通过sourceId 向 group写一个查询,看看组中所有记录的状态是否为2(已激活),并且还获得状态为的行的modifiedDate的MAX每组2(激活)。

结果表应该类似于sourceId,IsAllActivated,MaxModifiedForActivatedRecords。

我尝试了很多选项,比如Partition By,Cross over等,它们给了我一个列,而不是两个。具有自联接的选项成本很高,因此寻找任何其他有效的查询形式。

数据:

SourceId |国家| modifiedDate

s1 | 1 | 01/01

s1 | 2 | 01/02

s2 | 3 | 02/03

s2 | 3 | 03/03

s1 | 3 | 10/10

输出继电器:

sourceId | IsAllActivated | MaxModifiedForActivatedRecords

s1 | 0 | 02/03

s2 | 1 | 03/03

我曾尝试过:

SELECT
[SourceID]
,CASE
    WHEN COUNT(DISTINCT State) = 1 AND 
    SUM(DISTINCT State) = 3
    THEN 1
    ELSE 0
END AS IsAllActivated
FROM ThreadActivation
GROUP BY SourceID

SELECT
[SourceID]
,MAX(modifiedDate) AS MaxModifiedForActivatedRecords
FROM ThreadActivation
GROUP BY SourceID
HAVING State = 3

我可以单独获取它们,但不能在一个查询中一起使用。

我尝试使用行号进行排名:

WITH ThreadActivationTransaction AS (
        select 
         *
        ,ROW_NUMBER() over(PARTITION BY SourceId order by modifiedDate desc) AS rk
        from ThreadActivation)
        select 

        [sourceID]
      ,CASE 
          WHEN COUNT(DISTINCT State) = 1 AND SUM(DISTINCT State) = 3 
          THEN 1 
          ELSE 0
       END AS IsAllActivated
      ,[SourceId]
    from ThreadActivation s
        GROUP by SourceId  --where s.rk =1 

所有这些都没有让我突破。

1 个答案:

答案 0 :(得分:6)

您可以使用聚合和case

执行此操作
select sourceId,
       (case when max(state) = min(state) and max(state) = 2
             then 1 else 0
        end) as IsAllActivated,
       max(case when state = 2 then modifiedDate end) as MaxModifiedForActivatedRecords
from t
group by sourceId;

这假定state不是NULL。如果可能的话,逻辑只会稍微复杂一些。