我遇到了一个问题,那就是将一个值与另一个具有相同键的表中的另一个最新(但不是相同日期)值相乘。
为便于理解,我将在下面进行解释。
假设我们有两个表variables
和coefficients
:
表coefficients
date key coeff
-----------------------------
2019-06-01 A 1
2019-06-02 B 2
2019-06-03 A 3
2019-06-05 B 4
2019-06-06 B 5
2019-06-08 A 6
表variables
date key var
---------------------------
2019-06-02 A 7
2019-06-05 B 8
2019-06-05 A 9
2019-06-06 B 10
2019-06-07 A 11
2019-06-08 B 12
2019-06-09 A 13
目标是将variable
列上的值与最近的coeff
值相乘。
最后,我们将得到如下结果:
---------------------------
date key val <-- var * coeff
---------------------------
2019-06-02 A 7 <-- 7 * 1
2019-06-05 B 16 <-- 8 * 2
2019-06-05 A 27 <-- 9 * 3
2019-06-06 B 40 <-- 10 * 4
2019-06-07 A 33 <-- 11 * 3
2019-06-08 B 60 <-- 12 * 5
2019-06-09 A 78 <-- 13 * 6
在variables
表上,第一行(键A
)的日期为2019-06-02
,因此我们将variables.var
与上一个最近的日期(不是同一日期)相乘{ coefficients.coeff
中的{1}},即A
的{{1}}。与2019-06-01
的第二行相同。
我不知道从哪里开始查询,因为如果我们在每个coeff
上B
进行查询似乎都不起作用。
答案 0 :(得分:0)
请尝试以下代码获取所需的输出。子查询将考虑系数(小于变量)。日期(Date)。
您可以检查小提琴Demo here。
SELECT A.date,
A.[key],
A.var * ISNULL(
(
SELECT TOP 1 coeff
FROM coefficients B
WHERE B.[key] = A.[key]
AND B.date < A.date
ORDER BY B.date DESC
),1) val
FROM variables A
答案 1 :(得分:0)
快速而肮脏的解决方案:
SELECT
result.[date],
result.[key],
result.[var] * result.[coeff] AS val
FROM (
SELECT
v.[date],
v.[key],
v.[var],
(SELECT
c.coeff
FROM
dbo.coefficients c
WHERE
c.[key] = v.[key]
AND
c.[date] = (SELECT MAX(c1.[date])
FROM dbo.coefficients c1
WHERE c1.[key] = v.[key] AND c1.[date] < v.[date])) AS coeff
FROM
dbo.variables v
) result
您可以考虑编写一个最接近日期的函数:
CREATE FUNCTION dbo.ClosestDate(
@key nvarchar(1),
@date date
)
RETURNS date
AS
BEGIN
DECLARE @result date
SELECT @result = MAX(c.[date]) FROM dbo.coefficients c WHERE c.[key] = @key AND c.[date] < @date
RETURN @result
END
然后您可以将查询编写为:
SELECT
v.[date],
v.[key],
v.[var] * c.coeff AS [val]
FROM
dbo.variables v
INNER JOIN dbo.coefficients c ON c.[key] = v.[key] AND c.[date] = dbo.ClosestDate(v.[key], v.[date])
答案 2 :(得分:0)
我推荐outer apply
:
select v.*, (c.coeff * v.var)
from variables v outer apply
(select top (1) c.*
from coefficients c
where c.date <= v.date
order by c.date desc
) v;