我使用的是SQL 2008。
我有一个逻辑实体(表)说数据带属性(列)(键,日期,a,b,c,d)。
问题是a和b每天都会改变值,c和d会随机改变值并且非常慢。而且它们也会针对每个键单独更改。比如c = d,key = 1将在今天和下个月改变,密钥= 2明天和一周后。
所以我的想法是拆分2. MainData(键,日期,a,b)和TemporalData(键,changeDate,c,d)
但是我没有写出有效的查询 - 如何使用它。
我在考虑某种“参数化”视图(不确定它是否可行)。假设从vwData中选择*,其中date ='xxxxx',它将返回给我一个特定日期的b,以及c,d,它们对特定的密钥和该日期有效。
我需要一种简单明了的方法来从这个构造中选择数据。我还需要它有效率,因为数据在一年内会很大
(注意:只会选择date = @singleDate之间的日期之间)
示例:
MainData TemporalData
1 20101001 1.0 2.0 1 20101001 2.0 3.0
1 20101002 2.0 3.0 1 20101003 8.0 9.0
1 20101003 4.0 5.0
1 20101004 6.0 3.0
select * from vwData where date = '20101002'
1 20101002 2.0 3.0 2.0 3.0
select * from vwData where date = '20101003'
1 20101003 4.0 5.0 8.0 9.0
select * from vwData where date = '20101004'
1 20101004 6.0 3.0 8.0 9.0
答案 0 :(得分:1)
首先,将数据拆分为一个表中更多静态数据的1:1关系,以及另一个表中经常更改的数据并不是一个糟糕的方法。其次,不清楚TemporalData.ChangeDate是否应与MainDate匹配。[Date]。假设是这种情况,那么你可以这样做:
Select MainData.Key, MainData.[Date], MainData.a, MainData.b
, TemporalData.c, TemporalData.d
From MainData
Left Join TemporalData
On TemporalData.Key = MainData.Key
And TemporalData.ChangeDate = MainDate.[Date]
Where MainData.[Date] = @SomeDate
这假设您将始终具有MainData值,但可能没有TemporalData值。您可以将其放在视图中,但无法指定参数。视图是一个虚拟表,因此表示一组无序行。因此,您的视图将如下所示:
Create View vwMain
As
Select MainData.Key, MainData.[Date], MainData.a, MainData.b
, TemporalData.c, TemporalData.d
From MainData
Left Join TemporalData
On TemporalData.Key = MainData.Key
And TemporalData.ChangeDate = MainDate.[Date]
然后你会像这样使用视图:
Select ...
From vwMain
Where [Date] = @SomeDate
修改强>
看起来你想要的是总是有一个表示最近日期的TemporalData行。虽然我们可以从您的评论和示例输出中推断出这一点,但您的描述并不清楚。所以,鉴于此,这是一个解决方案。显然,最终结果不包括示例源数据的公用表表达式:
With MainData As
(
Select 1 As [Key], '20101001' As [Date], 1.0 As A, 2.0 As B
Union All Select 1 As [Key], '20101002', 2.0, 3.0
Union All Select 1 As [Key], '20101003', 4.0, 5.0
Union All Select 1 As [Key], '20101004', 6.0, 3.0
)
, TemporalData As
(
Select 1 As [Key], '20101001' As [ChangeDate], 2.0 As C, 3.0 As D
Union All Select 1 As [Key], '20101003', 8.0, 9.0
)
, RankedResults As
(
Select MainData.[Key], MainData.[Date], MainData.a, MainData.b
, TemporalData.c, TemporalData.d, TemporalData.ChangeDate
, Row_Number() Over ( Partition By MainData.[Key], MainData.[Date]
Order By TemporalData.ChangeDate Desc ) As Num
From MainData
Join TemporalData
On TemporalData.Key = MainData.Key
And TemporalData.ChangeDate <= MainData.[Date]
)
Select *
From RankedResults
Where Num = 1
Order By [Date]