乘以其他表中的最新先前值

时间:2019-06-25 07:34:03

标签: sql sql-server

我遇到了一个问题,那就是将一个值与另一个具有相同键的表中的另一个最新(但不是相同日期)值相乘。

为便于理解,我将在下面进行解释。

假设我们有两个表variablescoefficients

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的第二行相同。

我不知道从哪里开始查询,因为如果我们在每个coeffB进行查询似乎都不起作用。

3 个答案:

答案 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;