SQL日期分组-每个排列
当前在日期窗口中定义的多个记录存在问题。其中一些窗口交叉或多窗口交叉。 我需要做的是获得有效从和有效到的正确顺序窗口 以下是当前数据集:SQL日期分组-每个排列,sql,sql-server,tsql,Sql,Sql Server,Tsql,当前在日期窗口中定义的多个记录存在问题。其中一些窗口交叉或多窗口交叉。 我需要做的是获得有效从和有效到的正确顺序窗口 以下是当前数据集: ╔═════╦═══════════════╦═════════════╗ ║ Row ║ EffectiveFrom ║ EffectiveTo ║ ╠═════╬═══════════════╬═════════════╣ ║ 1 ║ 7/12/2010 ║ 15/01/2012 ║ ╠═════╬═══════════════╬══════
╔═════╦═══════════════╦═════════════╗
║ Row ║ EffectiveFrom ║ EffectiveTo ║
╠═════╬═══════════════╬═════════════╣
║ 1 ║ 7/12/2010 ║ 15/01/2012 ║
╠═════╬═══════════════╬═════════════╣
║ 2 ║ 1/01/2012 ║ 31/12/2042 ║
╠═════╬═══════════════╬═════════════╣
║ 3 ║ 15/01/2012 ║ 17/04/2012 ║
╠═════╬═══════════════╬═════════════╣
║ 4 ║ 17/04/2012 ║ 15/11/2012 ║
╠═════╬═══════════════╬═════════════╣
║ 5 ║ 15/11/2012 ║ 1/06/2013 ║
╠═════╬═══════════════╬═════════════╣
║ 6 ║ 1/06/2013 ║ 9/09/2013 ║
╠═════╬═══════════════╬═════════════╣
║ 7 ║ 9/09/2013 ║ 21/01/2020 ║
╠═════╬═══════════════╬═════════════╣
║ 8 ║ 23/12/2016 ║ 28/12/2019 ║
╠═════╬═══════════════╬═════════════╣
║ 9 ║ 23/12/2016 ║ 21/02/2020 ║
╠═════╬═══════════════╬═════════════╣
║ 10 ║ 21/01/2020 ║ 1/01/2100 ║
╠═════╬═══════════════╬═════════════╣
║ 11 ║ 21/02/2020 ║ 24/06/2100 ║
╚═════╩═══════════════╩═════════════╝
该数据的预期输出如下所示:
╔═══════════╦═══════════════╦═════════════╗
║ Row ║ EffectiveFrom ║ EffectiveTo ║
╠═══════════╬═══════════════╬═════════════╣
║ 1 ║ 7/12/2010 ║ 1/01/2012 ║
╠═══════════╬═══════════════╬═════════════╣
║ 1,2 ║ 1/01/2012 ║ 15/01/2012 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,3 ║ 15/01/2012 ║ 17/04/2012 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,4 ║ 17/04/2012 ║ 15/11/2012 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,5 ║ 15/11/2012 ║ 1/06/2013 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,6 ║ 1/06/2013 ║ 9/09/2013 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,7 ║ 9/09/2013 ║ 23/12/2016 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,7,8,9 ║ 23/12/2016 ║ 28/12/2019 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,7,9 ║ 28/12/2019 ║ 21/01/2020 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,9,10 ║ 21/01/2020 ║ 21/02/2020 ║
╠═══════════╬═══════════════╬═════════════╣
║ 2,9,10,11 ║ 21/02/2020 ║ 31/12/2042 ║
╠═══════════╬═══════════════╬═════════════╣
║ 9,10,11 ║ 31/12/2042 ║ 1/01/2100 ║
╠═══════════╬═══════════════╬═════════════╣
║ 11 ║ 1/01/2100 ║ 24/06/2100 ║
╚═══════════╩═══════════════╩═════════════╝
不幸的是,我的大脑似乎已经达到了极限,无法在SQL中找到解决方法。您可以生成时间框架,然后使用相关子查询或横向联接:
with dates as (
select v.dte as fromdate,
lead(v.dte) over (order by v.dte) as todate
from t cross apply
(values (effdate), (enddate)
) v(dte)
group by v.dte
)
select t.rows, d.*
from dates cross apply
(select string_agg(row, ',') as rows
from t
where dates.fromdate < t.enddate and
dates.todate >= t.effdate
) t;
我最后做了以下几件事:
SELECT
ROW_NUMBER() OVER (ORDER BY RDate) AS 'DateRow',
*
INTO #Windows FROM (
SELECT EffectiveFrom AS 'RDate'
FROM #Windows
UNION
SELECT EffectiveTo AS 'RDate'
FROM #Windows) [Windows]
SELECT
[StartDate].RDate AS 'Start',
[EndDate].RDate AS 'End'
FROM #Windows [StartDate]
LEFT JOIN #Windows [EndDate] ON [StartDate].DateRow = [EndDate].DateRow - 1
一旦我正确地构建和订购了它,我就会执行以下操作:
SELECT
ROW_NUMBER() OVER (ORDER BY RDate) AS 'DateRow',
*
INTO #Windows FROM (
SELECT EffectiveFrom AS 'RDate'
FROM #Windows
UNION
SELECT EffectiveTo AS 'RDate'
FROM #Windows) [Windows]
SELECT
[StartDate].RDate AS 'Start',
[EndDate].RDate AS 'End'
FROM #Windows [StartDate]
LEFT JOIN #Windows [EndDate] ON [StartDate].DateRow = [EndDate].DateRow - 1
看起来效果很好,给了我预期的结果