使用多个UNION和ORDER BY选择TOP

时间:2016-12-23 14:36:40

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

我想从SQL Server中的数据库中选择最新记录。如果仅选择一个项目,则最终输出为:

SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%OS%' AND Distrito LIKE '%' 

+总是在最后添加:

ORDER BY Data DESC

注意Distrito LIKE '%'必须保留,因为它有时会以编程方式更改为%以外的其他内容。

如果选择了更多项目,则查询会为每个项目以编程方式添加一行UNION。最后,ORDER BY一如既往地添加。选中所有4个项目的示例:

SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%OS%' AND Distrito LIKE '%' 
UNION ALL SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Rad%' AND Distrito LIKE '%' 
UNION ALL SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Aci%' AND Distrito LIKE '%'
UNION ALL SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Out%' AND Distrito LIKE '%' 
ORDER BY Data DESC

但是这给了我排序WHERE的每个BY Data DESC子句的 OLDEST 10个结果。

我如何获得每个项目的{strong>最新 X结果(WHERE)?

1 个答案:

答案 0 :(得分:0)

如果我理解正确,你想要每个tipo的10个最新的事件,如os,rad,aci,out。您可以通过查看数据来确定最新数据(我假设这是一个日期字段)我们可以通过tipo使用ROW_NUMBER分区来完成此操作,而不需要所有联合。但是因为我们有tipo的外卡,我们需要将它们定义为同一组;这可以通过窗口函数中的case语句来完成。

我假设Distrito在填充时对每个tipo都有相同的值。

WITH CTE AS (
    SELECT E.*, Row_number() over (partition by 
      CASE WHEN Tipo LIKE '%OS%' then 'OS' 
           WHEN Tipo like '%Rad%' then 'Rad'
           WHEN Tipo LIKE '%Aci%' then 'ACI'
           WHEN tipo LIKE '%Out%' then 'OUT' end order by data Desc) RN
    FROM dbo.Eventos E 
    WHERE (Tipo LIKE '%OS%' OR Tipo LIKE '%Rad%' OR Tipo LIKE '%Aci%' OR Tipo LIKE '%Out%') 
      AND Distrito like '%')
SELECT * 
FROM  cte 
WHERE RN <=10;

我们使用公用表表达式(CTE),因为在我们可以限制它们之前,我们需要为rownumbers生成结果。由于row_number将针对每个不同的tipo重新启动,我们只需要获得那些&lt; = 10来替换你的顶部。

或者只是建立你所做的......

SELECT * FROM (
  SELECT * FROM 
  (SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%OS%' AND Distrito LIKE '%' ORDER BY DATA desc) A 
  UNION ALL
  SELECT * FROM  
  (SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Rad%' AND Distrito LIKE '%' ORDER BY DATA DESC) B
  UNION ALL 
  SELECT * FROM 
  (SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Aci%' AND Distrito LIKE '%' ORDER BY DATA DESC) C
  UNION ALL 
  SELECT * FROM 
  (SELECT TOP(10) * from dbo.Eventos WHERE Tipo LIKE '%Out%' AND Distrito LIKE '%' ORDER BY Data DESC) D
) E
ORDER BY DATA DESC;

您需要子查询拥有自己的顺序,才能为每个tipo分组获得正确的前10名。要实现此目的,您需要将每个查询充当内联视图,并在联合发生之前完全实现(实际生成数据)。