在有序查询中使用union all

时间:2012-07-03 16:20:56

标签: sql sql-server

我正在处理这个需要排序行(order by)和union语句的查询。我想做的是根据每个客户的时间获取最新的读数。我知道我不能在联盟声明中使用秩序,但有没有办法实现我想要的?我还有几个表与select语句一起加入。以下是我的示例查询:

select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0001' 
(order by Time desc)
union all
select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0002' 
(order by Time desc)
union all
select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0003' 
(order by Time desc)

所以我正在寻找可以产生这些结果的东西。有谁知道这种方法?谢谢

3 个答案:

答案 0 :(得分:3)

您所要做的就是将order by子句放在整个查询的末尾。

select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0001' 

union all
select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0002' 

union all
select  top 1 name, ID, Date, Time, Cust_ID
from Table1
join Table2
on ID = Cust_ID
join Table3
on c = d
where ID = 'ID0003' 
order by ID, Time desc

已编辑的说明

请注意我在上述Order by子句中所做的更改。它将首先按ID按升序排序,然后按客户的时间降序排序。

答案 1 :(得分:1)

select * from (
select  top 1 name, ID, Date, Time, Cust_ID from Table1
join Table2 on ID = Cust_ID
join Table3 on c = d
where ID = 'ID0001' 
union all
select  top 1 name, ID, Date, Time, Cust_ID from Table1
join Table2 on ID = Cust_ID
join Table3 on c = d
where ID = 'ID0002' 
union all
select  top 1 name, ID, Date, Time, Cust_ID from Table1
join Table2 on ID = Cust_ID
join Table3 on c = d
where ID = 'ID0003')
order by ID, Time desc

答案 2 :(得分:1)

这似乎是一个经典的问题。在SQL Server 2005或更高版本中,它可以在ROW_NUMBER()函数的帮助下轻松解决:

WITH ranked AS (
  SELECT
    name, ID, Date, Time, Cust_ID,
    rnk = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Time DESC)
  FROM Table1
  JOIN Table2 ON ID = Cust_ID
  JOIN Table3 ON c = d
  WHERE ID = 'ID0001'
)
SELECT name, ID, Date, Time, Cust_ID
FROM ranked
WHERE ID IN ('ID0001', 'ID0002', 'ID0003')
  AND rnk = 1

也就是说,使用ROW_NUMBER(),按照ID的降序对每组行中的行进行排名Time,然后选择排名靠前且属于特定排名的行组(即具有特定ID值)。