基于SQL Server中日期的不同计数

时间:2018-10-29 11:56:41

标签: sql sql-server

我正在尝试根据下表创建一个新表:

SubjectNumber    TestDates    
001              11/12/12
001              01/10/15
001              04/03/13
002              05/21/14
003              08/06/15
002              09/12/18
002              03/30/12
003              09/07/18
004              10/14/11
005              02/05/14
005              02/06/14

我需要一个包含以下内容的新表:

1)主题编号

2)他们的第一次考试日期

3)他们的最后考试日期

4)测试总数

5)带有0和1的列,指示对象是否具有相隔至少30天的任何两个测试日期

新表应如下所示:

SubjectNumber    FirstTestDate     LastTestDate     TestCount    ThirtyDaysApart
001              11/12/12          01/10/15         3            1
002              03/30/12          09/12/18         3            1
003              08/06/15          09/07/18         2            1
004              10/14/11                           1            0
005              02/05/14          02/06/14         2            0

我正在使用SQL Server 2017。

我有一个临时表#Temp1,我想将数据存储在其中。该表称为#Temp。

Insert into #Temp1
SELECT SubjectNumber, WHERE 
CASE MIN(TestDates) then FirstTestDate = TestDates
END
CASE MAX(TestDates) then LastTestDate = TestDates
END
FROM #Temp;

3 个答案:

答案 0 :(得分:4)

您可以使用lag()和条件聚合:

select subjectnumber, min(testdate), max(testdate),
       max(case when prev_testdate < dateadd(day, -30, testdate) then 1 else 0 end) as diff30
from (select t.*,
             lag(testdate) over (partition by subjectnumber order by testdate) as prev_testdate
      from t
     ) t
group by subjectnumber;

答案 1 :(得分:1)

唯一棘手的部分是检查一组中的两个日期是否相隔30天。请注意,如果 任何 两个日期(不一定是连续的)相隔30天,则以下查询将返回1:

WITH cte AS (
    SELECT SubjectNumber, MIN(TestDates) FirstTestDate, MAX(TestDates) LastTestDate, COUNT(TestDates) TestCount
    FROM @yourdata
    GROUP BY SubjectNumber
)
SELECT *
FROM cte AS t
CROSS APPLY (
    SELECT CASE WHEN COUNT(*) = 0 THEN 0 ELSE 1 END AS ThirtyDaysApart
    FROM @yourdata AS o
    INNER JOIN @yourdata AS n ON o.SubjectNumber = n.SubjectNumber AND n.TestDates >= DATEADD(DAY, 30, o.TestDates)
    WHERE o.SubjectNumber = t.SubjectNumber
) AS CA

DB Fiddle

答案 2 :(得分:1)

您可以尝试使用lag()函数

select subjectnumber,min(TestDates),max(TestDates),count(TestDates),
case when count(case when pdatediff=30 then 1 end)>=2 then 1 else 0 end as ThirtyDaysApart
from
(
select subjectnumber,TestDates,COALESCE (DATEDIFF(DAY, 
       LAG(TestDates) OVER (PARTITION BY subjectnumber
            ORDER BY TestDates), TestDates) ,0) as pdatediff
from tablenmae
)X group by subjectnumber