通过另一个值查找值
Looking up value by another value
我是 运行 SQL Server 2016,遇到以下问题,这看起来很基本,但我无法解决。我有一个 table Prices
,它包含不同证券的价格,列
idTag varchar(12) NOT NULL
ts datetime2 NOT NULL
price float NOT NULL
我还有另一个 table Data
列 idTag
和 ts
,其中标签完全匹配,但时间戳不匹配。我想找到Data
table每一行对应的价格(相当于时间上的常数插值)
例如,Prices
中的示例值可能是
idTag | ts | price
=================================
IBM | 2020-01-01 13:00 | 100.23
IBM | 2020-01-01 13:05 | 100.34
IBM | 2020-01-01 13:10 | 100.45
IBM | 2020-01-01 13:15 | 100.29
IBM | 2020-01-01 13:20 | 100.31
Data
table 的样本值可能是
idTag | ts
========================
IBM | 2020-01-01 13:01
IBM | 2020-01-01 13:03
IBM | 2020-01-01 13:17
IBM | 2020-01-01 13:18
IBM | 2020-01-01 13:20
预期输出为
idTag | ts | price
=================================
IBM | 2020-01-01 13:01 | 100.23
IBM | 2020-01-01 13:03 | 100.23
IBM | 2020-01-01 13:17 | 100.29
IBM | 2020-01-01 13:18 | 100.29
IBM | 2020-01-01 13:20 | 100.31
如果两个 table 中的时间戳都匹配,我可以写一个 INNER JOIN
,但在这里,时间戳不匹配。我也可以在代码中做到这一点,e.q。 Python 或 Java,但 Prices
有超过 1.5 亿行,我宁愿不读它。
在 SQL 中有没有办法做到这一点?
非常感谢
当然,使用解析将 ts 的下一个值复制到当前行,然后使用范围谓词:
select *
from
(select *, lead(ts) over(partition by idtag order by ts) as nextts from prices) p
inner join data d
on
d.idtag = p.idtag and
d.ts >= p.ts and
d.ts < p.nextts
where
idtag = 'IBM'
可能需要一段时间才能处理数亿行..
您可以在子查询中获取某个日期的最新价格。
select
idtag, ts,
(
select top(1) price
from prices p
where p.idtag = d.idtag
and p.ts <= d.ts
order by p.ts desc
) as price
from data d
order by idtag, ts;
(您也可以将此子查询移动到 FROM
子句并使用 CROSS APPLY
)。
推荐指数:
create index idx on prices(idtag, ts, price);
我是 运行 SQL Server 2016,遇到以下问题,这看起来很基本,但我无法解决。我有一个 table Prices
,它包含不同证券的价格,列
idTag varchar(12) NOT NULL
ts datetime2 NOT NULL
price float NOT NULL
我还有另一个 table Data
列 idTag
和 ts
,其中标签完全匹配,但时间戳不匹配。我想找到Data
table每一行对应的价格(相当于时间上的常数插值)
例如,Prices
中的示例值可能是
idTag | ts | price
=================================
IBM | 2020-01-01 13:00 | 100.23
IBM | 2020-01-01 13:05 | 100.34
IBM | 2020-01-01 13:10 | 100.45
IBM | 2020-01-01 13:15 | 100.29
IBM | 2020-01-01 13:20 | 100.31
Data
table 的样本值可能是
idTag | ts
========================
IBM | 2020-01-01 13:01
IBM | 2020-01-01 13:03
IBM | 2020-01-01 13:17
IBM | 2020-01-01 13:18
IBM | 2020-01-01 13:20
预期输出为
idTag | ts | price
=================================
IBM | 2020-01-01 13:01 | 100.23
IBM | 2020-01-01 13:03 | 100.23
IBM | 2020-01-01 13:17 | 100.29
IBM | 2020-01-01 13:18 | 100.29
IBM | 2020-01-01 13:20 | 100.31
如果两个 table 中的时间戳都匹配,我可以写一个 INNER JOIN
,但在这里,时间戳不匹配。我也可以在代码中做到这一点,e.q。 Python 或 Java,但 Prices
有超过 1.5 亿行,我宁愿不读它。
在 SQL 中有没有办法做到这一点? 非常感谢
当然,使用解析将 ts 的下一个值复制到当前行,然后使用范围谓词:
select *
from
(select *, lead(ts) over(partition by idtag order by ts) as nextts from prices) p
inner join data d
on
d.idtag = p.idtag and
d.ts >= p.ts and
d.ts < p.nextts
where
idtag = 'IBM'
可能需要一段时间才能处理数亿行..
您可以在子查询中获取某个日期的最新价格。
select
idtag, ts,
(
select top(1) price
from prices p
where p.idtag = d.idtag
and p.ts <= d.ts
order by p.ts desc
) as price
from data d
order by idtag, ts;
(您也可以将此子查询移动到 FROM
子句并使用 CROSS APPLY
)。
推荐指数:
create index idx on prices(idtag, ts, price);