如果结束日期为空,则按开始日期 Desc 排序,否则按结束日期排序

dan*_*l9x 0 sql-server sorting

我有一个包含活动列表的 SQL Server (RDBMS) 表。每个活动都有一个开始和结束日期。

要求是对它们进行排序,以便首先显示具有 NULL 结束日期的那些(建议“当前” - 开始日期降序),但具有开始和结束值的那些要在“的末尾排序当前”行并按 end_date 降序排序。

最后,开始和结束日期的所有值为 null 的值必须位于结果集的末尾。

具有结束日期但开始日期为空的值应在 END 日期 desc 片段中排序的第二部分中进行排序。

Jul*_*eur 5

您可以在 中使用CASE表达式ORDER BY

ORDER BY CASE WHEN EndDate IS NULL 0 ELSE 1 END ASC
    , EndDate DESC
    , StartDate DESC
Run Code Online (Sandbox Code Playgroud)

按顺序排序条件(链接):

  1. EndDate 为 NULL 的值将获得 0,其他值将获得 1。这用作第一个排序标准。
  2. 那么第二个条件是 EndDate。
  3. 最后关系将按开始日期排序。

如果全局顺序不是您所期望的,您可以使用 ASC 和 DESC 以及列顺序。

示例数据和查询:

DECLARE @data TABLE(id int identity(0, 1), StartDate date, EndDate date)
INSERT INTO @data(StartDate, EndDate) VALUES
    ('20160101', '20160105')
    , ('20160101', null)
    , ('20160101', '20160107')
    , ('20160102', '20160103')
    , ('20160102', '20160105')
    , ('20160102', null)
    --, (null, '20160105')
    --, (null, null);

SELECT * 
FROM @data
ORDER BY CASE WHEN EndDate IS NULL THEN 0 ELSE 1 END ASC
    , EndDate DESC
    , StartDate DESC
Run Code Online (Sandbox Code Playgroud)

输出:

id  StartDate   EndDate
5   2016-01-02  NULL
1   2016-01-01  NULL
2   2016-01-01  2016-01-07
4   2016-01-02  2016-01-05
0   2016-01-01  2016-01-05
3   2016-01-02  2016-01-03
Run Code Online (Sandbox Code Playgroud)

ORDER BY子句(链接)将在末尾放置双 NULL(开始 + 结束):

ORDER BY CASE 
          WHEN EndDate IS NULL AND StartDate IS NULL THEN 2 
          WHEN EndDate IS NULL THEN 0 
          ELSE 1 END ASC
    , EndDate DESC
    , StartDate DESC;

id | StartDate            | EndDate
5  | 2016-01-02 00:00:00  | NULL
1  | 2016-01-01 00:00:00  | NULL
2  | 2016-01-01 00:00:00  | 2016-01-07 00:00:00
4  | 2016-01-02 00:00:00  | 2016-01-05 00:00:00
0  | 2016-01-01 00:00:00  | 2016-01-05 00:00:00
6  | NULL                 | 2016-01-05 00:00:00
3  | 2016-01-02 00:00:00  | 2016-01-03 00:00:00
7  | NULL                 | NULL
Run Code Online (Sandbox Code Playgroud)