选择Postgres中不在GROUP BY中的列?

时间:2017-02-06 16:55:20

标签: sql postgresql greatest-n-per-group

所以我一直在sqlite3中工作,其中以下命令有效:

select origin_city, dest_city, actual_time 
FROM flights 
GROUP BY origin_city 
ORDER BY actual_time desc;

但是当尝试在psql中执行此操作时,它不喜欢dest_city和actual_time不在GROUP BY子句中。我正在尝试从每个起始位置选择最长的航班并显示起点,目的地和飞行时间。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

根据您更新的问题,您可以使用row_number窗口功能标记值为1的最长航班,依此类推,然后过滤最上一行:

select origin_city, dest_city, actual_time
from (
  select
    t.*,
    row_number() over (partition by origin_city order by actual_time desc) rn
  from flights t
) t where rn = 1;

答案 1 :(得分:0)

您可以在cte或子查询中使用ROW_NUMBER()函数:

WITH cte as (SELECT *
                    ,ROW_NUMBER() OVER(PARTITION BY origin_city ORDER BY actual_time DESC) RN 
              FROM flights
             )
SELECT origin_city, dest_city, actual_time 
FROM cte
WHERE RN = 1
ORDER BY actual_time DESC;

ROW_NUMBER()函数为每一行分配一个数字。 PARTITION BY是可选的,但用于为该组中的每个值开始编号,即:如果您PARTITION BY origin_city,那么对于每个唯一origin_city值,编号将从1开始。{ {1}}当然用于定义计数应该如何进行,并且在ORDER BY函数中是必需的。

当存在ROW_NUMBER()子句时,许多数据库不允许SELECT列表中的非聚合字段不在GROUP BY子句中,MySQL和SQLite会允许这样做,但在某些情况下它会返回不需要的结果。

答案 2 :(得分:0)

为什么现在为每个origin_city创建一个包含最大actual_time的临时表?

SELECT temp.origin_city, flights.dest_city, temp.actual_time 
FROM (
  SELECT origin_city, MAX(actual_time) actual_time 
  FROM flights 
  GROUP BY origin_city 
) temp
JOIN flights using (origin_city, actual_time)
ORDER BY temp.actual_time DESC