当第一个SELECT不返回任何值时,UNION返回NULL

时间:2018-08-14 15:21:32

标签: sql-server

嗨,我有一张桌子:T1包含两列Date和Price

T1

---------------------------
DATE           | PRICE    |
---------------------------
2018-07-25     |2.00      |
---------------------------
2018-06-20     |3.00      |
---------------------------
2017-05-10     |3.00      |
---------------------------

这是我的要求:

  1. 如果用户输入的日期不在数据库中,那么我需要在表T1中返回最后的价格和日期。
  2. 如果用户输入的日期优于或低于表T1中的日期之一,例如,如果用户输入的“ 2017-05-09”不在表T1中;我必须返回给定日期以上的下一个日期。在这种情况下,'2017-05-10'

我在脚本中使用UNION,但是当SELECT语句之一返回空值时,它将返回空值。

我正在使用CTE表:

DECLARE @DateEntered DATE

WITH HistoricalCTE (Date, Price, RowNumber) AS (
    SELECT R.Date,
           R.Price,
           ROW_NUMBER() OVER (PARTITION BY R.Date, R.Price ORDER BY Date DESC)
    FROM T1 R
    WHERE Date = @DateEntered
    UNION
    SELECT R.Date,
           R.Price,
           ROW_NUMBER() OVER (PARTITION BY R.Date, R.Price ORDER BY Date DESC)                             
    FROM T1 R
    WHERE Date < @DateEntered
    UNION
    SELECT R.Date,
           R.Price,
           ROW_NUMBER() OVER (PARTITION BY R.Date, R.Price ORDER BY Date DESC)
    FROM T1 R
    WHERE Date > @DateEntered
)

问题是,当我输入优于表T1中所有日期的日期时,由于第一个选择返回的是空值,因此我得到的结果为空。关于我将如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:1)

您可能使这个复杂化了。如果我正确地阅读了您的问题,我们可以采用比输入值小的更大值,或者如果该值不存在,则取最大的表格。

WITH cte AS (
    SELECT *,
        ROW_NUMBER() OVER (ORDER BY Date) rn
    FROM T1
    WHERE Date > @DateEntered
)

SELECT
    CASE WHEN EXISTS (SELECT 1 FROM cte WHERE rn = 1)
         THEN (SELECT Date FROM cte WHERE rn = 1)
         ELSE (SELECT MAX(Date) FROM T1) END AS Date,
    CASE WHEN EXISTS (SELECT 1 FROM cte WHERE rn = 1)
         THEN (SELECT Price FROM cte WHERE rn = 1)
         ELSE (SELECT Price FROM T1 WHERE Date = (SELECT MAX(Date) FROM T1)) END AS Price;

Demo

在上面的演示中,所有边缘情况似乎都可以使用,您可以根据示例数据测试任何输入日期。