将结果分组成连续的时间段(日期)。

huangapple go评论65阅读模式
英文:

Grouping result in continuous periods (dates)

问题

你想要的SQL查询结果是查找连续的分组,如果 Period_End 与前一行相同或者 Period_start 是前一行的 Period_End 的后一天,那么这一行属于同一组。在这个测试中,有两个组:第1行到第7行和第8行到第12行。

你已经在 TEST 列中描述了这个结果。

英文:

I have the following SQL (including test data)

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TEST]') AND type in (N'U'))
	DROP TABLE [dbo].[TEST]

CREATE TABLE [dbo].[TEST](
	[CPR] [varchar](50) NULL,
	[Period_start] [date] NULL,
	[Period_End] [date] NULL,
	[Funktion] [varchar](50) NULL,
	[Gruppe] [varchar](50) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[TEST] ([CPR], [Period_start], [Period_End], [Funktion], [Gruppe]) VALUES 
	(N'111111-1111', CAST(N'2022-09-13' AS Date), CAST(N'2022-09-13' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-12-21' AS Date), CAST(N'2022-12-21' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-12-31' AS Date), CAST(N'2022-12-31' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-07-11' AS Date), CAST(N'2022-07-11' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-07-11' AS Date), CAST(N'2022-07-11' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-07-13' AS Date), CAST(N'2022-07-13' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-07-14' AS Date), CAST(N'2022-07-14' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-07-22' AS Date), CAST(N'2022-07-22' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-08-17' AS Date), CAST(N'2022-08-17' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-11-07' AS Date), CAST(N'2022-11-07' AS Date), N'53859', N'002'),
	(N'111111-1111', CAST(N'2022-11-24' AS Date), CAST(N'2022-11-24' AS Date), N'53859', N'002')

GO 

;with CTE_BASE as
(
	SELECT 
		CPR,
		DATEFROMPARTS(YEAR(Period_start), MONTH(Period_start), 1) Period_start,
		EOMONTH(Period_End) Period_End,
		EOMONTH(LAG(Period_End) OVER (PARTITION BY o.CPR, Funktion, o.Gruppe ORDER BY Period_start, Period_End)) Previous_EOM_Period_End
	FROM 
		TEST AS O
)
SELECT
   * ,  
	 CASE Previous_EOM_Period_End
        WHEN  NULL THEN 0
        WHEN Period_End THEN 1
        WHEN DATEADD(Day, -1, Period_start) then 1 
        ELSE 0
     END AS TEST	
FROM 
	CTE_BASE

and here is the result

CPR	Ydelse_startdato	Ydelse_slutdato	Previous_EOM_Ydelse_slutdato	TEST
CPR	Period_start	Period_End	Previous_EOM_Period_End	TEST
111111-1111	2022-07-01	2022-07-31	NULL	0
111111-1111	2022-07-01	2022-07-31	2022-07-31	1
111111-1111	2022-07-01	2022-07-31	2022-07-31	1
111111-1111	2022-07-01	2022-07-31	2022-07-31	1
111111-1111	2022-07-01	2022-07-31	2022-07-31	1
111111-1111	2022-08-01	2022-08-31	2022-07-31	1
111111-1111	2022-09-01	2022-09-30	2022-08-31	1
111111-1111	2022-11-01	2022-11-30	2022-09-30	0
111111-1111	2022-11-01	2022-11-30	2022-11-30	1
111111-1111	2022-12-01	2022-12-31	2022-11-30	1
111111-1111	2022-12-01	2022-12-31	2022-12-31	1
111111-1111	2022-12-01	2022-12-31	2022-12-31	1

I'm trying to locate continuous groups. A line belong to the same group if Period_End has the same value at in the previous line or Period_start is the day after Period_End

In this test we have two groups: Line 1-7 and line 8-12

I have tried to describe it in the TEST column

答案1

得分: 1

以下是已翻译的代码部分:

;with CTE_BASE as
(
    SELECT 
        CPR,
        Funktion,
        Gruppe,
        DATEFROMPARTS(YEAR(Period_start), MONTH(Period_start), 1) Period_start,
        EOMONTH(Period_End) Period_End,
        EOMONTH(LAG(Period_End) OVER (PARTITION BY o.CPR, Funktion, o.Gruppe ORDER BY Period_start, Period_End)) Previous_EOM_Period_End
    FROM 
        TEST AS O
)
SELECT
  * ,  
  COUNT(CASE WHEN Previous_EOM_Period_End IS NULL OR Previous_EOM_Period_End < DATEADD(Day, -1, Period_start) then 1 END)
    OVER (PARTITION BY CPR, Funktion, Gruppe ORDER BY Period_start, Period_End ROWS UNBOUNDED PRECEDING)   
FROM 
    CTE_BASE;

db<>fiddle

英文:

You need the following conditional running count

;with CTE_BASE as
(
    SELECT 
        CPR,
        Funktion,
        Gruppe,
        DATEFROMPARTS(YEAR(Period_start), MONTH(Period_start), 1) Period_start,
        EOMONTH(Period_End) Period_End,
        EOMONTH(LAG(Period_End) OVER (PARTITION BY o.CPR, Funktion, o.Gruppe ORDER BY Period_start, Period_End)) Previous_EOM_Period_End
    FROM 
        TEST AS O
)
SELECT
  * ,  
  COUNT(CASE WHEN Previous_EOM_Period_End IS NULL OR Previous_EOM_Period_End &lt; DATEADD(Day, -1, Period_start) then 1 END)
    OVER (PARTITION BY CPR, Funktion, Gruppe ORDER BY Period_start, Period_End ROWS UNBOUNDED PRECEDING)   
FROM 
    CTE_BASE;

db<>fiddle

huangapple
  • 本文由 发表于 2023年6月29日 15:49:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定