在每个组中找到最大值

时间:2019-02-04 19:04:45

标签: sql sql-server subquery

我有一张表格,其中包含有关城市之间航班的信息,如下所示:

origin_city dest_city   time    
Dothan AL   Atlanta GA    171       
Dothan AL   Elsewhere AL    2      
Boston MA   New York NY     5    
Boston MA   City MA         5    
New York NY Boston MA       5        
New York NY Poughkipsie NY  2

我想为每个出发城市返回最大飞行时间以及与之相关的一个或多个目的地城市。因此结果将如下所示:

Dothan AL    Atlanta GA    171
Boston MA    New York NY   5
Boston MA    City MA       5
New York NY  Boston MA     5

基于Reason for Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause之类的其他线程,我编写了一个查询,该查询返回了每个出发城市的最大飞行时间:

SELECT DISTINCT   F.origin_city AS origin_city, Max(F.actual_time) AS actual_time
FROM     Flights AS F
GROUP BY F.origin_city
ORDER BY F.origin_city

但是,当我尝试包含与该时间匹配的目的地时,会遇到各种错误。例如:

SELECT DISTINCT   F.origin_city AS origin_city, Max(F.actual_time) AS actual_time, F.dest_city AS dest_city
FROM     Flights AS F
GROUP BY F.origin_city
HAVING
    (MAX(F.actual_time) = F.actual_time)
ORDER BY F.origin_city
GO

...给我的错误是“ HAVING子句中的列'Flights.actual_time'无效,因为它不在聚合函数或GROUP BY子句中。”我尝试将F.actual_time添加到分组依据,但随后得到了很多结果,因为我获得了每个始发地/目的地对的最大飞行时间(我认为)。另外,actual_time字段应包含在一个汇总函数中:Max。

此代码:

SELECT F.origin_city AS origin_city, Max(F.actual_time) AS actual_time, F.dest_city AS dest_city
FROM Flights as F
WHERE F.actual_time IN (SELECT MAX(actual_time) FROM Flights AS F2 GROUP BY F2.origin_city) 
GROUP BY F.origin_city

出现类似的错误:在选择列表中,列'Flights.dest_city'无效,因为该列既不包含在聚合函数中,也不包含在GROUP BY子句中。

如何正确返回所有3列?

2 个答案:

答案 0 :(得分:0)

您想要RANK()

SELECT F.*
FROM (SELECT F.*,
             RANK() OVER (PARTITION BY origin_city ORDER BY time DESC) AS SEQ
      FROM Flights AS F
     ) F
WHERE SEQ = 1;

如果我使用您的版本,我会做的:

SELECT F.*
FROM Flights as F
WHERE F.actual_time = (SELECT MAX(F2.actual_time) 
                       FROM Flights AS F2 
                       WHERE F2.origin_city = F.origin_city
                      ); 

您的GROUP BY对于outersubquery都是不必要的,只需在outer query中传递F.origin_city引用(subquery)({{ 1}})以使其成为关联子查询。

答案 1 :(得分:0)

您可以将已经拥有的查询加入到Flights列与origin_city中的actual_time到查询中的Flights匹配的表max_actual_time中: / p>

SELECT F.*   
FROM Flights AS F INNER JOIN (
SELECT 
  origin_city, 
  Max(actual_time) AS max_actual_time
FROM Flights
GROUP BY origin_city) AS T
ON T.origin_city = F.origin_city AND T.max_actual_time = F.actual_time
ORDER BY F.origin_city