SM4*_*SM4 3 sql-server-2008 join sql-server greatest-n-per-group
假设我有两个表DailyTable和QuarterlyTable,每个表都有 3 列:ID、Date和Value。
顾名思义,DailyTable存储数据的频率是每天,而QuarterlyTable存储数据的频率是季度。
如何连接这两个表,以便根据ID和Date 将每个表中的最新(时间点)数据结合起来获得每日结果?
ID | Date | Value |
---------+---------+------------
1 |1/1/2010 | 10 |
1 |1/2/2010 | 15 |
...
1 |3/1/2010 | 20 |
...
1 |4/1/2010 | 30 |
Run Code Online (Sandbox Code Playgroud)
ID | Date | Value |
---------+---------+------------
1 |1/1/2010 | 1000 |
1 |4/1/2010 | 2000 |
...
Run Code Online (Sandbox Code Playgroud)
ID | Date | Value | Most Recent Quarterly Value
---------+---------+-------------------------------------------
1 |1/1/2010 | 10 | 1000
1 |1/2/2010 | 15 | 1000
...
1 |3/1/2010 | 20 | 1000
...
1 |4/1/2010 | 30 | 2000
Run Code Online (Sandbox Code Playgroud)
我正在处理财务数据,其中日表存储股票价格、交易量等,而季度表存储财务信息,例如净收入、收入。季度数据的更新频率取决于每个公司,因此假设每个季度有 90 天的间隔是不安全的。
开始和结束日期取决于 ID。QuarterStart 日期是每个 ID 不同的收益公布日期。该表有 3,000 个 ID。QuarterEnd 日期只是下一个 QuarterStart 日期 - 1 个工作日(在金融行业,Fiscal 和 Calendar 季度是两个相似但不完全相同的术语。两者都是季度,但日历年基于固定的日期范围,而 Fiscal 则基于公告) .
我正在寻找不需要创建和维护另一个表的解决方案。
这是一个解决方案,用于CROSS APPLY
查找在每日日期或之前结束的最新季度的值。如果您的表由 索引(ID, Date)
,则此查询将非常有效,只需一行查找每个每日日期的季度值。
此解决方案也不需要日历表,并且不对季度的持续时间进行假设。但是,它确实假设您的季度表中没有空白。例如,如果您缺少一年中的季度,则解决方案会将“最近一个季度”标识为一年前发生的季度。这可能完全没问题,但您至少应该意识到这个假设。
CREATE TABLE #DailyTable (ID INT, DailyTableDate DATE, Value INT)
CREATE TABLE #QuarterlyTable (ID INT, QuarterlyTableDate DATE, Value INT)
ALTER TABLE #QuarterlyTable ADD UNIQUE CLUSTERED (ID, QuarterlyTableDate)
INSERT INTO #DailyTable (ID, DailyTableDate, VALUE) VALUES (1,'2010-01-01',10)
INSERT INTO #DailyTable (ID, DailyTableDate, VALUE) VALUES (1,'2010-02-01',15)
INSERT INTO #DailyTable (ID, DailyTableDate, VALUE) VALUES (1,'2010-03-01',20)
INSERT INTO #DailyTable (ID, DailyTableDate, VALUE) VALUES (1,'2010-04-01',30)
INSERT INTO #QuarterlyTable (ID, QuarterlyTableDate, VALUE) VALUES (1,'2010-01-01',1000)
INSERT INTO #QuarterlyTable (ID, QuarterlyTableDate, VALUE) VALUES (1,'2010-04-01',2000)
SELECT d.ID,
d.DailyTableDate AS Result_Date,
d.Value,
qt.Value AS Most_Recent_Quarterly_Values
FROM #DailyTable AS d
CROSS APPLY (
-- Find the value for latest quarter that ended on or before the daily date
SELECT TOP 1 q.Value
FROM #QuarterlyTable q
WHERE q.ID = d.ID
AND q.QuarterlyTableDate <= d.DailyTableDate
ORDER BY q.QuarterlyTableDate DESC
) qt
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
925 次 |
最近记录: |