Это должно быть что-то вроде:
Инициализация тестовой таблицы
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
Упрощение Я создаю список дней между BreakdownDate и IssueFixedDate, используя рекурсивный CTE, удаляя дни, которые появляются более одного раза, и считая дни.