Sql 重复天数时以分数形式计算持续时间

Sql 重复天数时以分数形式计算持续时间,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有以下测试数据,这些数据是通过以下查询生成的: select ID, SequenceID, [Sub Status Start Date], [Sub Status End Date], DateDiff(d,[Sub Status Start Date],[Sub Status End Date]) as [Duration Days] from SampleData 我不确定该怎么做的是,如果相同的开始日期和结束日期多次出现,则将持续时间计算为

我有以下测试数据,这些数据是通过以下查询生成的:

select 
    ID,
    SequenceID,
    [Sub Status Start Date],
    [Sub Status End Date],
    DateDiff(d,[Sub Status Start Date],[Sub Status End Date]) as [Duration Days]
from SampleData
我不确定该怎么做的是,如果相同的开始日期和结束日期多次出现,则将持续时间计算为重复数除以分数。这显示在屏幕截图中,对于ID 288,有4个重复项,因此将持续时间分为4到0.25个。对于ID 404,有3个,因此每个值为0.33。但是,对于ID239,只有1,所以它仍然是0

样本数据

CREATE TABLE [dbo].[SampleData](
    [ID] [int] NOT NULL,
    [SequenceID] [int] NOT NULL,
    [Sub Status Start Date] [datetime] NULL,
    [Sub Status End Date] [datetime] NULL
) ON [PRIMARY]

GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 1, CAST(N'2019-08-06T00:00:00.000' AS DateTime), CAST(N'2019-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 2, CAST(N'2019-08-06T00:00:00.000' AS DateTime), CAST(N'2019-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 3, CAST(N'2019-08-06T00:00:00.000' AS DateTime), CAST(N'2019-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 4, CAST(N'2019-08-06T00:00:00.000' AS DateTime), CAST(N'2019-08-06T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 5, CAST(N'2019-08-06T00:00:00.000' AS DateTime), CAST(N'2019-08-13T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 6, CAST(N'2019-08-09T00:00:00.000' AS DateTime), CAST(N'2019-08-09T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 7, CAST(N'2019-08-13T00:00:00.000' AS DateTime), CAST(N'2019-10-03T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (288, 8, CAST(N'2019-10-03T00:00:00.000' AS DateTime), CAST(N'2019-10-03T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 1, CAST(N'2019-11-02T00:00:00.000' AS DateTime), CAST(N'2019-11-03T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 2, CAST(N'2019-11-28T00:00:00.000' AS DateTime), CAST(N'2019-11-28T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 3, CAST(N'2019-11-28T00:00:00.000' AS DateTime), CAST(N'2019-11-28T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 4, CAST(N'2019-11-28T00:00:00.000' AS DateTime), CAST(N'2019-11-28T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 5, CAST(N'2019-11-28T00:00:00.000' AS DateTime), CAST(N'2019-11-29T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (404, 6, CAST(N'2019-11-29T00:00:00.000' AS DateTime), NULL)
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (239, 1, CAST(N'2019-06-25T00:00:00.000' AS DateTime), CAST(N'2019-06-25T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (239, 2, CAST(N'2019-06-25T00:00:00.000' AS DateTime), CAST(N'2019-06-26T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (239, 3, CAST(N'2019-06-26T00:00:00.000' AS DateTime), CAST(N'2019-06-28T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (239, 4, CAST(N'2019-06-28T00:00:00.000' AS DateTime), CAST(N'2019-08-04T00:00:00.000' AS DateTime))
GO
INSERT [dbo].[SampleData] ([ID], [SequenceID], [Sub Status Start Date], [Sub Status End Date]) VALUES (239, 5, CAST(N'2019-07-01T00:00:00.000' AS DateTime), CAST(N'2019-08-04T00:00:00.000' AS DateTime))
GO
试试这个答案

SELECT D.*
    ,DATEDIFF(DAY,[Sub Status Start Date],[Sub Status End Date]) Duration
    ,CAST(CASE WHEN DATEDIFF(DAY,[Sub Status Start Date],[Sub Status End Date])>0 THEN DATEDIFF(DAY,[Sub Status Start Date],[Sub Status End Date])
      ELSE CASE WHEN A.NoOfEntries = 1 THEN 0 ELSE 1.0/A.NoOfEntries END END AS NUMERIC(8,2)) AS WhatTheResultShouldBe
FROM SampleData D
LEFT JOIN (
  SELECT [ID]
    ,[Sub Status End Date] DateVal
    ,COUNT(1)NoOfEntries
  FROM SampleData
  WHERE [Sub Status Start Date] = [Sub Status End Date]
  GROUP BY [ID],[Sub Status End Date]
    )A ON A.ID = D.ID AND D.[Sub Status End Date] = A.DateVal
          AND DATEDIFF(DAY,[Sub Status Start Date],[Sub Status End Date]) = 0
输出:

|  ID | SequenceID | Sub Status Start Date |  Sub Status End Date | Duration | WhatTheResultShouldBe |
|-----|------------|-----------------------|----------------------|----------|-----------------------|
| 288 |          1 |  2019-08-06T00:00:00Z | 2019-08-06T00:00:00Z |        0 |                  0.25 |
| 288 |          2 |  2019-08-06T00:00:00Z | 2019-08-06T00:00:00Z |        0 |                  0.25 |
| 288 |          3 |  2019-08-06T00:00:00Z | 2019-08-06T00:00:00Z |        0 |                  0.25 |
| 288 |          4 |  2019-08-06T00:00:00Z | 2019-08-06T00:00:00Z |        0 |                  0.25 |
| 288 |          5 |  2019-08-06T00:00:00Z | 2019-08-13T00:00:00Z |        7 |                     7 |
| 288 |          6 |  2019-08-09T00:00:00Z | 2019-08-09T00:00:00Z |        0 |                     0 |
| 288 |          7 |  2019-08-13T00:00:00Z | 2019-10-03T00:00:00Z |       51 |                    51 |
| 288 |          8 |  2019-10-03T00:00:00Z | 2019-10-03T00:00:00Z |        0 |                     0 |
| 404 |          1 |  2019-11-02T00:00:00Z | 2019-11-03T00:00:00Z |        1 |                     1 |
| 404 |          2 |  2019-11-28T00:00:00Z | 2019-11-28T00:00:00Z |        0 |                  0.33 |
| 404 |          3 |  2019-11-28T00:00:00Z | 2019-11-28T00:00:00Z |        0 |                  0.33 |
| 404 |          4 |  2019-11-28T00:00:00Z | 2019-11-28T00:00:00Z |        0 |                  0.33 |
| 404 |          5 |  2019-11-28T00:00:00Z | 2019-11-29T00:00:00Z |        1 |                     1 |
| 404 |          6 |  2019-11-29T00:00:00Z |               (null) |   (null) |                (null) |
| 239 |          1 |  2019-06-25T00:00:00Z | 2019-06-25T00:00:00Z |        0 |                     0 |
| 239 |          2 |  2019-06-25T00:00:00Z | 2019-06-26T00:00:00Z |        1 |                     1 |
| 239 |          3 |  2019-06-26T00:00:00Z | 2019-06-28T00:00:00Z |        2 |                     2 |
| 239 |          4 |  2019-06-28T00:00:00Z | 2019-08-04T00:00:00Z |       37 |                    37 |
| 239 |          5 |  2019-07-01T00:00:00Z | 2019-08-04T00:00:00Z |       34 |                    34 |
试试这个

SELECT ID,SequenceID,[Sub Status Start Date],[Sub Status End Date], DATEDIFF(d,[Sub Status Start Date],[Sub Status End Date]) AS [Duration Days],
       CASE WHEN Counts > 1 THEN CAST(1.0 / X.Counts AS DECIMAL(18,2)) 
            WHEN Counts = 1AND X.[Duration Days] > 0 THEN X.[Duration Days]
       ELSE 0 END [What The Result Should Be]
FROM
(
    SELECT ID,SequenceID,[Sub Status Start Date],[Sub Status End Date], DATEDIFF(d,[Sub Status Start Date],[Sub Status End Date]) AS [Duration Days],       
    Counts = COUNT(*) OVER (PARTITION BY ID,[Sub Status Start Date],[Sub Status End Date] ORDER BY ID)
    FROM SampleData
)X ORDER BY ID,SequenceID
请试试这个

SELECT s.ID
    ,SequenceID
    ,[Sub Status Start Date]
    ,[Sub Status End Date]
    ,DATEDIFF(DAY, [Sub Status Start Date], [Sub Status End Date]) Duration
    ,CAST(CASE 
            WHEN DATEDIFF(DAY, [Sub Status Start Date], [Sub Status End Date]) > 0
                THEN DATEDIFF(DAY, [Sub Status Start Date], [Sub Status End Date])
            ELSE CASE 
                    WHEN c.NumCount = 1
                        THEN 0
                    ELSE 1.0 / c.NumCount
                    END
            END AS NUMERIC(8, 2)) AS Result
FROM SampleData s
LEFT JOIN (
    SELECT [ID]
        ,[Sub Status End Date] Dated
        ,COUNT(1) NumCount
    FROM SampleData
    WHERE [Sub Status Start Date] = [Sub Status End Date]
    GROUP BY [ID]
        ,[Sub Status End Date]
    ) c ON c.ID = s.ID
    AND s.[Sub Status End Date] = c.Dated
    AND DATEDIFF(DAY, [Sub Status Start Date], [Sub Status End Date]) = 0
请检查此查询的结果