2016-08-20 101 views
0

我想按客戶分組&日期並生成2個單獨值(Flag = Y和Flag = N)的計數列。輸入表看起來是這樣的:SQL group by rows with separate separate

Customer Date Flag 
------- ------- ----- 
001  201201 Y 
001  201202 Y 
001  201203 Y 
001  201204 N 
001  201205 N 
001  201206 Y 
001  201207 Y 
001  201208 Y 
001  201209 N 
002   201201 N 
002   201202 Y 
002   201203 Y 
002   201205 N 

輸出應該是這樣的:

Customer MinDate MaxDate Count_Y 
------- ------ ------- ------- 
001  201201 201203  3 
001  201206 201208  3  
002  201202 201203  2  

如何我寫的SQL查詢?任何形式的幫助表示讚賞!謝謝!

+0

哪個RDBMS是爲了這個?請添加一個標籤來指定您是使用'mysql','postgresql','sql-server','oracle'還是'db2' - 或者其他的東西。 –

回答

1

想要查找「Y」的連續值。這是一個「間隙和孤島」問題,有兩種基本方法:

  • 確定每個組中的第一個「Y」並使用此信息來定義一組連續的「Y」值。
  • 使用row_number()值的差值進行計算。

第一個依賴於SQL Server 2012+,並且您尚未指定版本。所以,第二個看起來像這樣:

select customer, min(date) as mindate, max(date) as maxdate, 
     count(*) as numYs 
from (select t.*, 
      row_number() over (partition by customer order by date) as seqnum_cd, 
      row_number() over (partition by customer, flag order by date) as seqnum_cfd 
     from t 
    ) t 
where flag = 'Y' 
group by customer, (seqnum_cd - seqnum_cfd), flag; 

解釋這是如何工作的有點棘手。根據我的經驗,如果運行子查詢,您會看到seqnum列是如何計算的,並通過觀察結果來「得到它」。

注意:這假定每天至多有一條記錄。如果還有更多,您可以使用dense_rank()而不是row_number()來達到同樣的效果。

+0

非常感謝你:) – Cappu

0

請嘗試下面的查詢,它會給你正是你想要的。

DROP TABLE [GroupCustomer] 
GO 

CREATE TABLE [dbo].[GroupCustomer](
    Customer VARCHAR(50), 
    [Date] [datetime] NULL, 
    Flag VARCHAR(1) 
     ) 

INSERT INTO [dbo].[GroupCustomer] (Customer ,[Date],Flag) 
VALUES ('001','201201','Y'),('001','201202','Y'), 
     ('001','201203','Y'),('001','201204','N'), 
     ('001','201205','N'),('001','201206','Y'), 
     ('001','201207','Y'),('001','201208','Y'), 
     ('001','201209','N'),('002','201201','N'), 
     ('002','201202','Y'),('002','201203','Y'), 
     ('002','201205','N') 
GO 


;WITH cte_cnt 
AS 
(
SELECT Customer,Format(MIN([Date]),'yyMMdd') AS MinDate 
    ,Format(MAX([Date]),'yyMMdd') AS MaxDate 
    , COUNT('A') AS Count_Y 
FROM (
    SELECT Customer,Flag,[Date], 
     ROW_NUMBER() OVER(Partition by customer ORDER BY [Date]) AS ROW_NUMBER, 
     DATEDIFF(D, ROW_NUMBER() OVER(Partition by customer ORDER BY [Date]) 
     , [Date]) AS Diff 
    FROM [GroupCustomer] 
    WHERE Flag='Y') AS dt 
    GROUP BY Customer,Flag, Diff) 
SELECT * 
FROM cte_cnt c 
ORDER BY Customer 

GO 
+0

非常感謝您的幫助,但如果日期在兩行之間的日期不同,如上例 – Cappu

+0

INSERT INTO [dbo]。[GroupCustomer](Customer,[Date],Flag) VALUES('001' ('001','201204','Y'),('001','201202','Y'),('001','201202','Y'), ''), ('001','201207','N'),('001','201210','Y'), ('001','201211','Y'), '','201218','Y'), ('001','201219','N'),('002','201201','N'), ('002','201202' 'Y'),('002','201203','Y'), ('002','201205','N') GO – Cappu

+0

非常感謝你:) – Cappu