3

我有一张数据表,其中存储了不同日期不同商品的价格。

CREATE TABLE COMMODITIES(
    [MARKET_DATE] [datetime2](0) NOT NULL,
    [THE_TYPE] [numeric](2, 0) NOT NULL,
    [CLOSE_VALUE] [numeric](10, 4) NULL,
) ON [PRIMARY]

GO

MARKET_DATE保存交易日期(日期按升序排列,但不连续)

CLOSE_VALUE持有价格

THE_TYPE持有商品的类型。

每种商品的交易日期不同。


我需要获取THE_TYPE= 1 的所有日期的列表、价格以及THE_TYPE= 2的商品的相应价格


如果每种商品的交易日期相同,我可以做一个简单的连接(相当于 ExcelVLOOKUP (, false)

SELECT mr1.market_date
    ,mr1.close_value,mr2.close_value

FROM commodities mr1
LEFT JOIN commodities  mr2 ON mr1.market_date = mr2.market_date
    AND mr2.the_type = 2
WHERE mr1.the_type = 1

但是,由于交易日期不一样,我需要寻找与 Excel 等效的非精确匹配VLOOKUP (, true)- 即最大日期在mr2该日期或之前mr1.market_date


我正在寻找一个简洁的解决方案。作为一种解决方法,我可以将中间日期输入到数据库中,这样就可以了。或者,我可以执行以下操作

SELECT mr1.market_date
    ,mr1.close_value
    , 

            (SELECT top 1 close_value
            FROM commodities mr2

            where mr2.market_date <= mr1.market_date
                AND mr2.the_type = 2
                order by market_date desc
            ) AS close_value

FROM commodities mr1
WHERE mr1.the_type = 1

但我希望有一个更整洁(更快)的解决方案


例如,如果表包含以下内容

MARKET_DATE CLOSE_VALUE  THE_TYPE
    2012-01-01  300  1
    2012-01-03  310  1
    2012-01-05  310  1
    2012-01-01  400  2
    2012-01-02  420  2
    2012-01-05  430  2

我会得到

2012-01-01  300  400
2012-01-03  310  420
2012-01-05  310  430
4

2 回答 2

2

您可以使用交叉应用。对于这种情况,它可能会稍微快一些,但可能并不明显:

SELECT mr1.market_date
    ,mr1.close_value as close_value_1
    ,p.close_value as close_value_2
FROM commodities mr1
cross apply
  (SELECT top 1 close_value
        FROM commodities mr2
        where mr2.market_date <= mr1.market_date
            AND mr2.the_type = 2
            order by market_date desc) p
  WHERE mr1.the_type = 1

看到它在行动

于 2013-07-04T16:05:50.917 回答
1
WITH OrderedOrders AS
(
    SELECT mr1.market_date
          ,mr1.close_value as mr1close
          ,mr2.close_value as mr2close
          ,ROW_NUMBER() OVER (PARTITION BY mr1.market_date ORDER BY mr2.market_date desc) AS RowNumber
    FROM commodities mr1
    JOIN commodities mr2
      ON mr2.market_date <= mr1.market_date
     AND mr2.the_type = 2
     AND mr1.the_type = 1 
)  
SELECT market_date, mr1close, mr2close  
FROM OrderedOrders 
WHERE RowNumber = 1
于 2013-07-04T15:44:39.690 回答