gpt4 book ai didi

SQL 自连接和聚合

转载 作者:行者123 更新时间:2023-11-29 14:11:30 25 4
gpt4 key购买 nike

我在 postgres 中有一个具有以下结构的表

表格路径: 乘客、出发地、目的地、日期、月份、年份

我想根据一年内在一条路线上旅行的乘客数量找到前 3 条路线。一条路线上的乘客总数(A <-> B) = 乘客总数(A -> B) + 乘客总数( B->A )

聚合路线上乘客数量的最佳/最佳方式是什么,表格行数约为 1.5 亿行。

谢谢

最佳答案

有两种方法可以做到这一点。一种是聚合,另一种是连接。

select least(origin, dest) as od1, greatest(origin, dest) as od2, sum(passengers) as numpassengers
from path t
group by least(origin, dest), greatest(origin, dest)
order by numpassengers
limit 3;

另一种是自连接。如果每个方向只有一行,则可以不聚合:

select p1.origin, p1.dest, p1.passengers + p2.passengers as numpassengers
from path p1 join
path pt2
on p1.origin = p2.dest and p1.dest = p2.origin
where p1.origin < p1.dest
order by numpassengers desc
limit 3;

否则,您需要自连接和聚合,因此第一种方法可能更快:

select p1.origin, p1.dest, sum(p1.passengers + p2.passengers) as numpassengers
from path p1 join
path pt2
on p1.origin = p2.dest and p1.dest = p2.origin
where p1.origin < p1.dest
group by p1.origin, p1.dest
order by numpassengers desc
limit 3;

我不知道哪个效率更高。但是,我怀疑按总和计算的前 3 条路线会在每个方向的前 100 名中。如果是这样,在 numpassengers 上建立一个索引,然后尝试:

select least(origin, dest) as od1, greatest(origin, dest) as od2, sum(passengers) as numpassengers
from path t cross join
(select min(passengers) as cutoff
from (select distinct passengers
from path
order by passengers desc
limit 100
) t
) minp
where numpassengers >= minp.cutoff
group by least(origin, dest), greatest(origin, dest)
order by numpassengers
limit 3;

截断的计算应该只使用索引,大大减少其余查询的负载。

编辑:

如果您没有least()greatest(),只需使用case 语句:

select (case when origin < dest then origin else dest end) as od1,
(case when origin < dest then dest else origin end) as od2,
sum(passengers) as numpassengers
from path t
group by 1, 2
order by numpassengers
limit 3;

您可以在group by 中重复case 语句。但是 Amazon Redshift 允许您在 group by 子句中引用列别名或位置。

关于SQL 自连接和聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21530049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com