在使用Studio的SQL Server 2012中:我需要显示的结果显示不同的客户端编号(CN)的数量,以便重新输入,按类型分组,如下所示:
Type CountOfCN
5 1
10 3
仅重新输入计数(ENTRY_NO 1从不计数),并且必须在该客户编号的上一个条目结束之后超过2天。因此,基本上ENTRY_NO 1不计算在内。 ENTRY_NO 2计算开始日期是否比ENTRY_NO 1的结束日期晚2天以上,依此类推,例如ENTRY_NO 3、4、5。
创建表时,我通过执行ROW_NUMBER函数获得了ENTRY_NO。我不知道如何创建datediff或dateadd函数(?)来查看上一行的结束日期,并使用每个CN的开始日期进行计算?
这是我的桌子:
CN STARTDATE ENDDATE TYPE ENTRY_NO
1 1/1/2018 1/20/2018 10 1
1 1/21/2018 1/30/2018 5 2
1 2/3/2018 NULL 10 3
2 1/1/2018 1/20/2018 10 1
2 1/27/2018 1/30/2018 10 2
3 1/1/2018 1/20/2018 5 1
3 1/27/2018 1/30/2018 10 2
3 2/10/2018 2/20/2018 5 3
4 1/7/2018 1/30/2018 5 1
5 1/27/2018 1/30/2018 5 1
5 1/31/2018 NULL 5 2
因此,结果中的行应为CN 1的ENTRY_NO 2,CN 2的ENTRY_NO 2,CN 3的ENTRY_NO 2&3。
只有最后一个条目可能/可能没有NULL结束日期
答案 0 :(得分:1)
使用LAG窗口功能,您可以获取上一个结束日期。
SELECT *
FROM
(
SELECT * ,
LAG(ENDDATE) OVER (PARTITION BY CN ORDER BY STARTDATE) AS prevEndDate
FROM yourtable
) q
WHERE DATEDIFF(d, prevEndDate, STARTDATE) > 2
AND ENDDATE IS NOT NULL
答案 1 :(得分:0)
根据您要执行的条件将表内部联接到自身:
Entry_No
1 Entry_No
比另一侧要大CN
使用该联接创建CTE或派生表,然后从中进行选择,按Type
分组并获得COUNT(*)
答案 2 :(得分:0)
所以这最终比我最初想象的要复杂得多,但是在这里...
您可以在SSMS中运行此示例。
创建一个符合您上面定义的表变量:
DECLARE @data TABLE ( CN INT, STARTDATE DATETIME, ENDDATE DATETIME, [TYPE] INT, ENTRY_NO INT );
插入给出的数据:
INSERT INTO @data ( CN, STARTDATE, ENDDATE, [TYPE], ENTRY_NO ) VALUES
( 1, '1/1/2018', '1/20/2018', 10, 1 )
, ( 1, '1/21/2018', '1/30/2018', 5, 2 )
, ( 1, '2/3/2018', NULL, 10, 3 )
, ( 2, '1/1/2018', '1/20/2018', 10, 1 )
, ( 2, '1/27/2018', '1/30/2018', 10, 2 )
, ( 3, '1/1/2018', '1/20/2018', 5, 1 )
, ( 3, '1/27/2018', '1/30/2018', 10, 2 )
, ( 3, '2/10/2018', '2/20/2018', 5, 3 )
, ( 4, '1/7/2018', '1/30/2018', 5, 1 )
, ( 5, '1/27/2018', '1/30/2018', 5, 1 )
, ( 5, '1/31/2018', NULL, 5, 2 );
确认插入的数据:
+----+-------------------------+-------------------------+------+----------+
| CN | STARTDATE | ENDDATE | TYPE | ENTRY_NO |
+----+-------------------------+-------------------------+------+----------+
| 1 | 2018-01-01 00:00:00.000 | 2018-01-20 00:00:00.000 | 10 | 1 |
| 1 | 2018-01-21 00:00:00.000 | 2018-01-30 00:00:00.000 | 5 | 2 |
| 1 | 2018-02-03 00:00:00.000 | NULL | 10 | 3 |
| 2 | 2018-01-01 00:00:00.000 | 2018-01-20 00:00:00.000 | 10 | 1 |
| 2 | 2018-01-27 00:00:00.000 | 2018-01-30 00:00:00.000 | 10 | 2 |
| 3 | 2018-01-01 00:00:00.000 | 2018-01-20 00:00:00.000 | 5 | 1 |
| 3 | 2018-01-27 00:00:00.000 | 2018-01-30 00:00:00.000 | 10 | 2 |
| 3 | 2018-02-10 00:00:00.000 | 2018-02-20 00:00:00.000 | 5 | 3 |
| 4 | 2018-01-07 00:00:00.000 | 2018-01-30 00:00:00.000 | 5 | 1 |
| 5 | 2018-01-27 00:00:00.000 | 2018-01-30 00:00:00.000 | 5 | 1 |
| 5 | 2018-01-31 00:00:00.000 | NULL | 5 | 2 |
+----+-------------------------+-------------------------+------+----------+
运行SQL以根据您的业务规则获取类型计数:
T-SQL:
SELECT
[TYPE], COUNT( DISTINCT CN ) AS ClientCount
FROM @data
WHERE
CN IN (
SELECT DISTINCT CN FROM (
SELECT
dat.CN
, dat.ENTRY_NO
, dat.[TYPE]
, DATEDIFF( DD
, LAG( ENDDATE, 1, NULL ) OVER ( PARTITION BY CN ORDER BY CN, ENDDATE ) -- gets enddate for previous CN entry
, ENDDATE
) AS DayDiff
FROM @data dat
) AS Clients
WHERE
Clients.ENTRY_NO >= 2
AND Clients.DayDiff > 2
)
GROUP BY
[TYPE]
ORDER BY
[TYPE];
返回:
+------+-------------+
| TYPE | ClientCount |
+------+-------------+
| 5 | 2 |
| 10 | 3 |
+------+-------------+
快速浏览一下IN子查询,就会发现在“ TYPE”计数期间将包含CN 1、2和3。
SELECT
dat.CN
, dat.ENTRY_NO
, dat.[TYPE]
, DATEDIFF( DD
, LAG( ENDDATE, 1, NULL ) OVER ( PARTITION BY CN ORDER BY CN, ENDDATE ) -- gets enddate for previous CN entry
, ENDDATE
) AS DayDiff
FROM @data dat
ORDER BY
dat.CN, dat.ENTRY_NO;
+----+----------+------+---------+
| CN | ENTRY_NO | TYPE | DayDiff |
+----+----------+------+---------+
| 1 | 1 | 10 | NULL |
| 1 | 2 | 5 | 10 |
| 1 | 3 | 10 | NULL |
| 2 | 1 | 10 | NULL |
| 2 | 2 | 10 | 10 |
| 3 | 1 | 5 | NULL |
| 3 | 2 | 10 | 10 |
| 3 | 3 | 5 | 21 |
| 4 | 1 | 5 | NULL |
| 5 | 1 | 5 | NULL |
| 5 | 2 | 5 | NULL |
+----+----------+------+---------+