将ORDER BY与UNION ALL一起使用

时间:2013-12-06 13:39:21

标签: sql sql-server tsql union union-all

我有一个包含事件日期列的表。我想按顺序返回记录,其中首先显示最近的记录,当所有即将到来的记录结束时,过去的记录应该显示最新的记录。

为此,我计划首先获得event date > GETDATE()按升序排序的记录,并按照事件日期的降序将其与其余记录合并。

由于在ORDER BY中无法指定2 UNION子句,因此可以使用哪种方法。

总结一下,我的查询需要结果如下:

SELECT EventName, EventDate
FROM EventTable 
WHERE EventDate>GETDATE()
ORDER BY EventDate

UNION ALL

SELECT EventName, EventDate
FROM EventTable 
WHERE EventDate<=GETDATE()
ORDER BY EventDate DESC

4 个答案:

答案 0 :(得分:4)

SELECT * 
FROM 
(
  SELECT EventName, EventDate, 1 AS OrderPri, 
    ROW_NUMBER() OVER(ORDER BY EventDate) AS Row
  FROM EventTable 
  WHERE EventDate > GETDATE()
  UNION ALL
  SELECT EventName, EventDate, 2 AS OrderPri, 
    ROW_NUMBER() OVER(ORDER BY EventDate DESC) AS Row
  FROM EventTable 
  WHERE EventDate <= GETDATE()
) AS m
ORDER BY m.OrderPri, m.Row

答案 1 :(得分:2)

您需要指定适用于所有结果的ORDER BY,如果您希望首先显示第一个SELECT的结果,则必须< em>指定:

SELECT EventName,EventDate FROM (
  SELECT EventName, EventDate, 1 as ResultSet
  FROM EventTable 
  WHERE EventDate>GETDATE()

  UNION ALL

  SELECT EventName, EventDate, 2
  FROM EventTable 
  WHERE EventDate<=GETDATE()
) t
ORDER BY ResultSet,
         CASE WHEN ResultSet = 1 THEN EventDate END,
         CASE WHEN ResultSet = 2 THEN EventDate END DESC

严格来说,第二个CASE表达式不是必需的,但我已将它包含在对称中。


或者,正如Allan建议的那样,也许只是:

SELECT EventName, EventDate
FROM EventTable 
ORDER BY
     CASE WHEN EventDate > GETDATE() THEN 1 ELSE 2 END,
     CASE WHEN EventDate > GETDATE() THEN EventDate END,
     EventDate desc

(这次我省略了最后的CASE表达式)

答案 2 :(得分:1)

您只能在最终查询中添加ORDER BY:

SELECT EventName, EventDate
FROM EventTable 
WHERE EventDate>GETDATE()

UNION ALL

SELECT EventName, EventDate
FROM EventTable 
WHERE EventDate<=GETDATE()
ORDER BY EventDate DESC

基本上 - 它接受第一个查询,将它与第二个查询联合起来并按顺序排序。 如果你想要一个不同的顺序,你需要在两个查询中引入一个排序键,然后按那个排序。

但是在您的示例中,我认为您需要重新考虑查询,并且可能会在ORDER BY中查看ROW_NUMBER或CASE,因此您无需联合。

答案 3 :(得分:1)

另一个替代方案,如@Linger's answer,使用CTE,但有点不同,因为它完全丢弃UNION ALL并执行单次扫描而不是两次扫描(或两次搜索,如果{{1有一个覆盖索引)。这与@Damien's second query具有相同的计划,但只需与EventDate进行一次比较(我发现它有点整洁)。

GETDATE()

always reference the schema并尝试养成terminating statements with a semi-colon的习惯。

相关问题