我有一个包含事件日期列的表。我想按顺序返回记录,其中首先显示最近的记录,当所有即将到来的记录结束时,过去的记录应该显示最新的记录。
为此,我计划首先获得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
答案 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的习惯。