有人可以向我解释这里发生了什么。这种行为并不像我期望的那样:
select category,timefield from test where category='A'
union
select top 10 category,timefield from test where category='B' order by timefield desc
我想要的是A类的所有行,只有B类中最近的10行 执行时,结果实际上是:所有类别A(按时间字段降序排序)+ 第一个 10行B类(按时间字段降序排序)
更奇怪的是,如果我们把这整个语句放在一个子查询中,我希望这个行为保持不变并像以前那样进行评估,但事实并非如此:
select * from (
select category,timefield from test where category='A'
union
select top 10 category,timefield from test where category='B' order by timefield desc
) subq
这将返回所有类别A(按升序排列)+最近的10类B类(按降序排列)。 这正是我想要的。
为什么第一个陈述没有产生我所期望的,为什么第二个陈述的表现非常不同?
(这是SQL Server 2008)
答案 0 :(得分:5)
您需要在第一个查询中使用括号,因为order by
会应用于union
的结果。它被解释为:
(select category,timefield from test where category='A'
union
select top 10 category,timefield from test where category='B'
)
order by timefield desc
(我不是说这是有效的语法。)
而你想要的是:
(select category, timefield from test where category='A')
union
(select top 10 category, timefield from test where category='B' order by timefield desc)
请注意union
将删除重复项。如果您不想要这笔额外费用,请改用union all
。
至于为什么这是一个子查询,我的猜测是巧合。当您在没有top
的情况下使用order by
时,SQL Server无法保证返回结果 - 甚至从一次调用到下一次调用时结果都是一致的。有时它实际上可能会做你想要的。