它应该是这样的:
测试表初始化
DROP TABLE BreakdownLog
CREATE TABLE BreakdownLog
(
EquipmentID INT,
ProblemID INT,
BreakdownDate DATETIME,
IssueFixedDate DATETIME NULL
);
INSERT INTO BreakDownLog VALUES (1, 1, '01-Jun-2011', '01-Sep-2011')
INSERT INTO BreakDownLog VALUES (1, 2, '01-Jun-2011', '01-Oct-2011')
INSERT INTO BreakDownLog VALUES (2, 1, '01-Jun-2011', '01-Oct-2011')
INSERT INTO BreakDownLog VALUES (2, 2, '01-Jun-2011', '01-Oct-2011')
INSERT INTO BreakDownLog VALUES (3, 1, '15-Jun-2011', '01-Sep-2011')
INSERT INTO BreakDownLog VALUES (3, 2, '10-Jun-2011', '25-Aug-2011')
INSERT INTO BreakDownLog VALUES (4, 1, '01-Jun-2011', '01-Aug-2011')
INSERT INTO BreakDownLog VALUES (4, 2, '10-Sep-2011', '22-Oct-2011')
INSERT INTO BreakDownLog VALUES (5, 1, '01-Jun-2011', '15-Jun-2011')
INSERT INTO BreakDownLog VALUES (5, 2, '02-Jun-2011', NULL)
真正的代码
-- We exchange the NULLs in IssueFixedDate with the current date
; WITH Base AS (
SELECT EquipmentID, ProblemID, BreakdownDate
, ISNULL(IssueFixedDate
, CONVERT(VARCHAR(10), GETDATE(), 101)) IssueFixedDate
-- The previous line generates the current date without time
FROM BreakDownLog
)
-- We generate a table with all the days the equipment was broken.
-- This is done through a recursive CTE
, BaseDays AS (
SELECT EquipmentID, BreakdownDate AS DefunctDay, IssueFixedDate FROM Base
UNION ALL
SELECT EquipmentID, DefunctDay + 1 AS DefunctDay, IssueFixedDate
FROM BaseDays
WHERE DefunctDay + 1 <= IssueFixedDate
-- In T-SQL if you add 1 to a DateTime it's equivalent to adding a day
)
-- We make a distinct on the days where the equipment was broken,
-- to delete days where the equipment was broken for two reasons
, BaseDaysDistinct AS (
SELECT DISTINCT EquipmentID, DefunctDay
FROM BaseDays
)
-- We group the equipment's DefunctDays by EquipmentID
SELECT EquipmentID, COUNT(*) DefunctDays
FROM BaseDaysDistinct
GROUP BY EquipmentID
我们可以在已经改变了过去两个选择:
SELECT EquipmentID, COUNT(DISTINCT DefunctDay) DefunctDays
FROM BaseDays
GROUP BY EquipmentID
简化我生成使用递归CTE BreakdownDate和IssueFixedDate之间的天列表,删除多次出现并数着日子更天。
+1 ....但aaaaah ...花了15分钟才能理解它,我不确定我能否以相同的方式重写它。 – xanatos
我不会使用spt_values表,因为它没有证件性质。但是,与xanatos给出的CTE相比,确实是一个非常简单的查询。 – Raghu
我会给你另外一个链接的+1,因为它非常有趣:-) – xanatos