【问题标题】:Sql query needs to sort on multiple date columns togethersql查询需要对多个日期列一起排序
【发布时间】:2012-05-21 01:03:02
【问题描述】:

我有一个包含三个日期字段的表格:开始日期、中期日期和结束日期。我想创建一个查询以从表中获取最新活动。本例中的活动是更新日期字段的时间。

无需编写 3 个单独的查询然后组合我的代码中的值来获取 10 个最近的活动,我可以在一个查询中执行此操作吗?所以现在我有

    SELECT TOP 10 * FROM core_table 
    ORDER BY [start_date] Desc

    SELECT TOP 10 * FROM core_table 
    ORDER BY [process_date] Desc

    SELECT TOP 10 * FROM core_table 
    ORDER BY [archive_date] Desc

所以我想将这三个查询的结果汇总在一起,以获得基于所有三个日期的前 10 个条目。

【问题讨论】:

  • 我认为获得每一行的第一行,而不是行的集合,但无论如何都有帮助。谢谢!
  • 我认为该帖子中 Sven 的解决方案应该对您有用,因为它有效地计算了每一行的最大日期。然后,您可以对此计算列进行排序和过滤: SELECT [other fields,] (SELECT Max(v) FROM (VALUES (date1),(date2),(date3),...) AS value(v)) as [ MaxDate],来自 [YourTable]
  • @Mike - 谢谢,我得到了我需要的答案。如果人们认为这是重复的,我可以关闭它,得到我需要的!

标签: sql sql-server select sql-order-by


【解决方案1】:

Raphaël Althaus' answer 的扩展:

CREATE TABLE core_table (
    ...
    max_date AS
        CASE
            WHEN start_date >= process_date AND start_date >= archive_date
                THEN start_date
            WHEN process_date >= archive_date
                THEN process_date
            ELSE archive_date
        END
);

CREATE INDEX core_table_ie1 ON core_table (max_date);

那么,你可以简单...

SELECT TOP 10 *
FROM core_table
ORDER BY max_date DESC;

...它应该使用索引范围扫描而不是全表扫描。

【讨论】:

    【解决方案2】:

    我觉得你需要UNION:

    SELECT TOP 10               
        *
    FROM
        (   ( SELECT TOP 10 
                  *, start_date    AS activity_date
              FROM core_table 
              ORDER BY [start_date] DESC
            ) 
        UNION
            ( SELECT TOP 10 
                  *, process_date  AS activity_date
              FROM core_table 
              ORDER BY [process_date] DESC
            ) 
        UNION
            ( SELECT TOP 10 
                  *, archive_date  AS activity_date
              FROM core_table 
              ORDER BY [archive_date] DESC
            )
        ) AS t
    ORDER BY activity_date DESC ;
    

    【讨论】:

    • 这是我最初的想法之一,但我的语法不正确,ORDER BY 子句必须在 UNION 之外。不确定这是 T-Sql 还是一般的 SQL。
    • 这行得通,谢谢。我坚持使用 Raphael 的 b/c 解决方案,它的附带好处是按合并日期排序。您的解决方案提供前 10 多行,但按主键列排序。
    • 查看我的编辑。您可以在代码的第一行中选择要更改 TOP 10 的 (30) 行中的多少。
    • @ypercube 我不认为这是正确的。 UNION 将比较所有字段,包括 activity_date,对于 same 表行可以有不同的值(因为它将从不同的字段中获取值)。您最终会得到不需要的重复项。
    • @Branko:你说对了。然后需要修改外部查询(除非 OP 正是想要这个,如果最近已经处理和更新了一行,则该行会出现多次)
    【解决方案3】:

    基于 Itiong_sh 给出的答案,这并不完全相同:您可以按 ORDER BY 进行操作

    select top 10 * from core_table
    order by
      CASE
          WHEN start_date >= process_date AND start_date >= archive_date 
              THEN  start_date
          WHEN process_date >= archive_date 
              THEN  process_date
          ELSE  archive_date
      END
     DESC
    

    【讨论】:

    • 就是这样,谢谢!我在 END 之后添加了 DESC 以按我想要的顺序获取日期,但这会处理多个日期字段!
    猜你喜欢
    • 2021-08-13
    • 1970-01-01
    • 2015-12-14
    • 2013-04-22
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多