【发布时间】:2016-11-16 15:28:06
【问题描述】:
我已搜索但找不到以下问题的解决方案。
我有几个价目表有几百万行,我发现了许多可以汇总到一行的示例,因为该组的开始日期和结束日期是连续的(结束日期:20151231 下一个开始日期:20160101)
但我也发现了许多差距,这意味着使用 min() 和 max() 函数的直接方法不适用,因为可能的差距将被忽略。
以下包含一个带有示例记录的#Price 表和一个带有我要拍摄的结果的#Target 表:
谢谢。
我对间隔的定义是两条连续记录之间的间隔超过 1 天。
if object_id('tempdb..#Prices', 'table') is not null
drop table #Prices
;
create table #Prices (
Product varchar(50) not null
, Value decimal(18,5) not null
, ValidFrom date not null
, ValidTo date null
)
insert into #Prices
(
Product
, Value
, ValidFrom
, ValidTo
)
select
Product = 'Island A'
, Value = 10.10
, ValidFrom = '20140101'
, ValidTo = '20140606'
union all
select
Product = 'Island A'
, Value = 10.10
, ValidFrom = '20140607'
, ValidTo = '20141010'
union all
select
Product = 'Island A'
, Value = 10.11
, ValidFrom = '20141011'
, ValidTo = '20141231'
union all
select
Product = 'Island A'
, Value = 11.10
, ValidFrom = '20150101'
, ValidTo = '20151231'
union all
select
Product = 'Island A'
, Value = 10.10
, ValidFrom = '20160101'
, ValidTo = null
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20140101'
, ValidTo = '20140606'
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20140607'
, ValidTo = '20141010'
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20150101'
, ValidTo = '20151231'
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20160101'
, ValidTo = null
select *
from #Prices as P
order by P.Product, P.ValidFrom
;
if object_id('tempdb..#Target', 'table') is not null
drop table #Target
;
create table #Target (
Product varchar(50) not null
, Value decimal(18,5) not null
, ValidFrom date not null
, ValidTo date null
)
insert into #Target
(
Product
, Value
, ValidFrom
, ValidTo
)
select
Product = 'Island A'
, Value = 10.10
, ValidFrom = '20140101'
, ValidTo = '20141010'
union all
select
Product = 'Island A'
, Value = 10.11
, ValidFrom = '20141011'
, ValidTo = '20141231'
union all
select
Product = 'Island A'
, Value = 11.10
, ValidFrom = '20150101'
, ValidTo = '20151231'
union all
select
Product = 'Island A'
, Value = 10.10
, ValidFrom = '20160101'
, ValidTo = null
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20140101'
, ValidTo = '20141010'
union all
select
Product = 'Gap B'
, Value = 20.10
, ValidFrom = '20150101'
, ValidTo = null
select *
from #Target as P
order by P.Product, P.ValidFrom
;
编辑 我希望编辑是您问题的答案。可以通过取 min(ValidFrom) 和 max(ValidTo) 来聚合连续的记录(记录之间最多 1 天)。问题在于差距,这些将被忽略。产品“差距 B”的结果将是一条记录。 即使日期在 Gap 期间,任何使用 Date 的记录都将获得值 20.10。
Gap B | 20.10 | 20140101 | null
因此我需要 2 条记录,因此表上的所有连接都将产生正确的值,而在 Gap 期间没有值
Gap B | 20.10 | 20140101 | 20141010
Gap B | 20.10 | 20151231 | null
【问题讨论】:
-
请仅显示您的表格数据示例,以及为什么这表明您存在间隙和孤岛问题。
-
@TimBiegeleisen,我对原始问题做了一点补充。我希望这很清楚。 Grzt 亚历山大
标签: sql tsql sql-server-2008-r2 gaps-and-islands