Cha*_*har 5 t-sql sql-server sql-server-2012
我有这些数据:
CREATE TABLE #student
(
student_id INT,
status VARCHAR(50),
created_dt DATE
)
CREATE TABLE #student_status_history
(
student_id INT,
from_status VARCHAR(50),
to_status VARCHAR(50),
status_changed_dt DATE
)
INSERT INTO #student (student_id, status, created_dt)
VALUES (1, 'Active', '2016-10-02'),
(2, 'Active', '2016-10-02'),
(3, 'Active', '2016-10-02')
SELECT *
FROM #student
Run Code Online (Sandbox Code Playgroud)
10月5日student2状态更新为inactive
UPDATE #student
SET status = 'Inactive'
WHERE student_id = 2
INSERT INTO #student_status_history (student_id, from_status, to_status, status_changed_dt)
VALUES (2, 'Active', 'Inactive', '2016-10-05')
SELECT *
FROM #student
SELECT *
FROM #student_status_history
Run Code Online (Sandbox Code Playgroud)
10月8日student2状态更新为active:
UPDATE #student
SET status = 'Active'
WHERE student_id = 2
INSERT INTO #student_status_history (student_id, from_status, to_status, status_changed_dt)
VALUES (2, 'InActive', 'Active', '2016-10-08')
Run Code Online (Sandbox Code Playgroud)
10月9日我创建了另一名学生:
INSERT INTO #student (student_id, status, created_dt)
VALUES (4, 'Active', '2016-10-09')
Run Code Online (Sandbox Code Playgroud)
10月10日我在表格中有这些数据.
select * from #student
select * from #student_status_history
Run Code Online (Sandbox Code Playgroud)
使用上面的表格
我应该在10月10日10月10日至10月10日期间生成一份报告
输出应如下
Date ActiveCount
----------- -----------
2016-10-01 0
2016-10-02 3
2016-10-04 3
2016-10-05 2
2016-10-06 2
2016-10-07 2
2016-10-08 3
2016-10-09 4
2016-10-10 4
Run Code Online (Sandbox Code Playgroud)
Pரத*_*ீப் 11
这是一种方法
您需要一个calendar包含日期列表的表格.我习惯于Recursive CTE在日期范围之间生成日期.
;WITH calendar
AS (SELECT dates = CONVERT(DATETIME, '2016-10-01')
UNION ALL
SELECT dates = Dateadd(DAY, 1, dates)
FROM calendar
WHERE dates < '2016-10-10')
SELECT c.dates,
Count(s.created_dt) AS ActiveCount
FROM calendar c
LEFT JOIN #student s
ON s.created_dt <= c.dates
WHERE NOT EXISTS (SELECT 1
FROM #student_status_history sh
WHERE sh.student_id = s.student_id
HAVING c.dates BETWEEN Min(CASE
WHEN from_status = 'active '
AND to_status = 'Inactive' THEN status_changed_dt
END) AND Max(CASE
WHEN to_status = 'active '
AND from_status = 'Inactive' THEN Dateadd(dd, -1, status_changed_dt)
END))
GROUP BY c.dates
OPTION (MAXRECURSION 0)
Run Code Online (Sandbox Code Playgroud)
结果:
?????????????????????????????????????????
? dates ? ActiveCount ?
?????????????????????????????????????????
? 2016-10-01 00:00:00.000 ? 0 ?
? 2016-10-02 00:00:00.000 ? 3 ?
? 2016-10-03 00:00:00.000 ? 3 ?
? 2016-10-04 00:00:00.000 ? 3 ?
? 2016-10-05 00:00:00.000 ? 2 ?
? 2016-10-06 00:00:00.000 ? 2 ?
? 2016-10-07 00:00:00.000 ? 2 ?
? 2016-10-08 00:00:00.000 ? 3 ?
? 2016-10-09 00:00:00.000 ? 4 ?
? 2016-10-10 00:00:00.000 ? 4 ?
?????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |