MSSQL:将日期范围考虑在内的独特的
我有一张桌子看起来不像那样:MSSQL:将日期范围考虑在内的独特的,sql,sql-server,distinct,Sql,Sql Server,Distinct,我有一张桌子看起来不像那样: K_PKEY D_FROM D_TO PERC ============ ==================== ==================== =========== 0013 01-JAN-2009 00:00:00 31-JUL-2011 00:00:00 0013 01-AUG-2011 00:00:00 31-DEC-2011 00:
K_PKEY D_FROM D_TO PERC
============ ==================== ==================== ===========
0013 01-JAN-2009 00:00:00 31-JUL-2011 00:00:00
0013 01-AUG-2011 00:00:00 31-DEC-2011 00:00:00
0013 01-JAN-2012 00:00:00 31-MAR-2012 00:00:00
0013 01-APR-2012 00:00:00 31-DEC-2012 00:00:00 75.000000
0013 01-JAN-2013 00:00:00 31-JAN-2013 00:00:00 50.000000
0013 01-FEB-2013 00:00:00 28-FEB-2013 00:00:00 50.000000
0013 01-MAR-2013 00:00:00 31-AUG-2013 00:00:00 75.000000
0013 01-SEP-2013 00:00:00 31-MAY-2015 00:00:00 75.000000
0013 01-JUN-2015 00:00:00 31-DEC-2100 00:00:00
我正在尝试构建一个考虑特定日期范围的DISTICT查询
这就是我想到的:
SELECT DISTINCT k_pkey, MIN(d_from), MAX(d_to), perc FROM my_table GROUP BY k_pkey
这不是我想要的方式,我明白为什么。
MIN()和MAX()与不同的全局工作相结合,这对于该类型的查询是很自然的。这导致:
K_PKEY D_FROM D_TO PERC
============ ==================== ==================== ===========
0013 01-JAN-2009 00:00:00 31-DEC-2100 00:00:00
0013 01-APR-2012 00:00:00 31-MAY-2015 00:00:00 75.000000
0013 01-JAN-2013 00:00:00 28-FEB-2013 00:00:00 50.000000
我想要实现的是保持时间顺序,只合并(可以这么说)相邻的范围
K_PKEY D_FROM D_TO PERC
============ ==================== ==================== ===========
0013 01-JAN-2009 00:00:00 31-MAR-2012 00:00:00
0013 01-APR-2012 00:00:00 31-DEC-2012 00:00:00 75.000000
0013 01-JAN-2013 00:00:00 28-FEB-2013 00:00:00 50.000000
0013 01-MAR-2013 00:00:00 31-MAY-2015 00:00:00 75.000000
0013 01-JUN-2015 00:00:00 31-DEC-2100 00:00:00
是否可以使用一个sql查询(如果可能的话,我不想使用sql过程)?有什么建议吗?您正试图根据日期和相同的
PERC
将相邻行合并在一起。其思想是使用左连接来确定哪些值开始一个新范围。然后,使用累计总和计算每行的启动次数。后一个值可用于分组
在SQL Server 2012+中,可以直接进行累计和。在早期版本中,您将使用外部应用
结果查询如下所示:
select k_pkey, min(d_from) as d_from, max(d_to) as d_to, perc
from (select t.*,
sum(IsGroupStart) over (partition by k_pkey, perc order by d_from) as grp
from (select t.*,
(case when t_prev.k_pkey is null then 1 else 0 end) as IsGroupStart
from t left join
t tprev
on tprev.k_pkey = t.k_pkey and
(tprev.perc = t.perc or tprev.perc is null and t.perc is null) and
tprev.d_to = dateadd(day, -1, t.d_from)
) t
) t
group by grp, k_pkey, perc;
哪个版本的SQL Server?根据这一点,您可以查看窗口函数(OVER子句)。但我怀疑,我是否真的理解了您的分组标准……我可能会使用游标来清理数据,并将清理后的数据插入临时表中。我将从第一条记录开始,并存储其开始和结束日期。然后,在查找相邻的范围时,我将遍历数据集并修改开始和结束日期。最后,我只需要对我的临时表中剩下的内容做一个选择2012@JessePetronio是的,这样做是可行的,但我非常渴望在一个查询中(由于几个原因)实现它!真不错@Gordon使用LAG()
查找新组何时开始,您认为如何<代码>(当isnull((滞后(e.perc)超过(d_from下的订单)),-1)e.perc然后1其他0结束)作为新组时的情况
谢谢-我很快会检查这一点并带着反馈回来,但这似乎正是我需要的:)@DavidIslaLAG()
是一个合理的替代方案,而不是自联接。