你没有提及这个名字是如何涉及的,所以我假设你想按名称完成。我将进一步假设,当你谈论“连续”时,你的意思是按照日期顺序,而不是以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