现在,我有一条选择语句返回此结果集:

|  date  | id  | price |
+--------+-----+-------+
| Jan 01 | XYZ | 5.00  |
| Jan 02 | XYZ | NULL  |
| Jan 03 | XYZ | NULL  |
| Jan 06 | XYZ | NULL  |
| Jan 07 | XYZ | 3.00  |
| Jan 08 | XYZ | NULL  |


问题是,如果值是XYZ,我想获取ID为NULL的行的产品的最后已知价格,但是如果是两天内,就只能获取该价格。因此,对于Jan 02Jan 03,我想查看Jan 01的值,而不是Jan 06的值。

这就是我的意思:

|  date  | id  | price |
+--------+-----+-------+
| Jan 01 | XYZ | 5.00  |
| Jan 02 | XYZ | 5.00  | (Jan 01)
| Jan 03 | XYZ | 5.00  | (Jan 01)
| Jan 06 | XYZ | NULL  | << Stays NULL
| Jan 07 | XYZ | 3.00  |
| Jan 08 | XYZ | 3.00  | (Jan 07)


这是表的定义:

CREATE TABLE dbo.catalogue
(
  [date] DATE NOT NULL ,
  [id] VARCHAR(3) NOT NULL ,
  [price] FLOAT
)


和样本数据:

INSERT  INTO dbo.catalogue
    ( [date], [id], [price] )
VALUES
    ( '2015-01-01', 'XYZ', 5.00 ),
    ( '2015-01-02', 'XYZ', NULL ),
    ( '2015-01-03', 'XYZ', NULL ),
    ( '2015-01-06', 'XYZ', NULL ),
    ( '2015-01-07', 'XYZ', 3.00 ),
    ( '2015-01-08', 'XYZ', NULL )


编辑:另外,我应该提到这是在存储过程的子查询中,因此性能绝对重要。

提前致谢。

最佳答案

使用APPLY的另一种解决方案:

SELECT
    c.[date],
    c.id,
    price = ISNULL(c.price, x.price)
FROM dbo.catalogue c
OUTER APPLY(
    SELECT TOP 1 price
    FROM dbo.catalogue
    WHERE
        DATEDIFF(DAY, [date], c.[date]) <= 2
        AND c.[date] > [date]
        AND id = c.id
    ORDER BY date DESC
)x

关于sql - 获取SQL Server 2008 R2中列的最后两个非空值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32190952/

10-15 16:54