你沒有提及這個名字是如何涉及的,所以我假設你想按名稱完成。我將進一步假設,當你談論「連續」時,你的意思是按照日期順序,而不是以id順序。最後,我還要假定你也將排除在連續5個零,連續6個零,等
有可能是一個更簡單的方法,但這應該工作:
;WITH Transitions_To_CTE AS
(
SELECT
T1.id,
T1.name,
T1.date,
T1.value
FROM
My_Table T1
LEFT OUTER JOIN My_Table T2 ON
T2.name = T1.name AND
T2.date < T1.date AND
T2.value <> 0
LEFT OUTER JOIN My_Table T3 ON
T3.name = T1.name AND
T3.date > COALESCE(T2.date, '1900-01-01') AND
T3.date < T1.date
WHERE
T1.value = 0 AND
T3.id IS NULL
),
Transitions_From_CTE AS
(
SELECT
T1.id,
T1.name,
T1.date,
T1.value
FROM
My_Table T1
LEFT OUTER JOIN My_Table T2 ON
T2.name = T1.name AND
T2.date > T1.date AND
T2.value <> 0
LEFT OUTER JOIN My_Table T3 ON
T3.name = T1.name AND
T3.date < COALESCE(T2.date, '9999-12-31') AND
T3.date > T1.date
WHERE
T1.value = 0 AND
T3.id IS NULL
),
Range_Exclusions AS
(
SELECT
S.name,
S.date AS start_date,
E.date AS end_date
FROM
Transitions_To_CTE S
INNER JOIN Transitions_From_CTE E ON
E.name = S.name AND
E.date > S.date
LEFT OUTER JOIN Transitions_From_CTE E2 ON
E2.name = S.name AND
E2.date > S.date AND
E2.date < E.date
WHERE
E2.id IS NULL AND
(SELECT COUNT(*) FROM dbo.My_Table T WHERE T.name = S.name AND T.date BETWEEN S.date AND E.date) >= 4
)
SELECT
T.id,
T.name,
T.date,
T.value
FROM
dbo.My_Table T
WHERE
NOT EXISTS (SELECT * FROM Range_Exclusions RE WHERE RE.name = T.name AND T.date BETWEEN RE.start_date AND RE.end_date)
有趣的是,只是想知道這需要..這是一個商業規則或只是學習過程? – VoodooChild 2010-06-24 17:10:25
這是業務需求。我們需要從整體計算中消除不良數據點。還有那個爵士樂。 – 2010-06-24 17:12:20