如何解决在Postgres中以高性能的方式获取最大值和相应的列
我有一个奇怪的情况。
假设我需要了解以下信息:对于给定的面包店,我需要了解有关他们最甜蜜的蛋糕的信息,以及有关所有最新糕点的信息。蛋糕。所以我们的数据看起来像这样。
-------------------------------------
bakery | name | created_timestamp | sweetness_score
marios | blueberry | 100 | 4
marios | razberry | 115 | 2
luigis | angels | 120 | 5
luigis | devils | 155 | 1
-------------------------------------
最终数据输出应类似于
{
mario:
sweetestCake:{
name: blueberry,sweetness_score: 4,created_timestamp: 100
},mostRecentCake: {
name: razberry,sweetness_score: 2,created_timestamp: 115
}
},luigi: // same concept but for luigi's cakes
我正在使用RANK窗口函数,并且仅在RANK = 1的地方进行选择。例如,可以通过以下方式找到最甜的蛋糕
SELECT * FROM (
SELECT RANK () OVER (PARTITION BY (BAKERY) ORDER BY sweetness_score DESC)
AS rank_of_sweetness
) as sweetness
WHERE rank_of_sweetness = 1;
但这不是很出色。
我用MAX
和窗口函数LAST_VALUE
弄了一个 lot 一个不同的主意,它们检索正确的sweetness_score
,但得到其他列我需要一直很痛苦。
如何才能更有效地做到这一点?还是不管,RANK都是我最好的选择吗?
解决方法
<?php
//Let's open the file
$list = fopen("list.txt","r");
$matches = array();
if ($list) {
while ($getLine = fgets($list)) {
$getLine = rtrim($getLine); // remove newline
$source = fopen("source.txt","r");
if ($source)
{
while ($buffer = fgets($source)) {
$buffer = rtrim($buffer);
if($buffer === $getLine)
$matches[] = $buffer;
}
fclose($source);
}
}
}
//show results:
print_r($matches);
解决方案很好,并且是解决该问题的规范方法之一:
rank()
在Postgres中,您也可以使用select *
from (
select t.*,rank() over(partition by bakery order by sweetness_score desc) rn1,rank() over(partition by bakery order by created_timestamp desc) rn2
from mytable t
)
where 1 in (rn1,rn2)
。这是一个方便的扩展,可能会进行优化。可以同时使用distinct on()
来同时获得两个结果(如果单行同时具有最大的甜美性和最新的时间戳,则有意代替union
):
union all
我很想知道Postgres 13中新的(
select distinct on(bakery) *
from mytable
order by bakery,sweetness_score desc
) union (
select distinct on(bakery) *
from mytable
order by bakery,created_timestamp desc
)
子句在这里是否会有所帮助。一个好处是,您可以使用它一次过滤两个匹配项(fetch
无法做到):
distinct on
如果上述方法均无济于事,则另一种方法是依靠相关子查询解决方案:
select *
from mytable
order by least(
rank() over(partition by bakery order by sweetness_score desc),rank() over(partition by bakery order by created_timestamp desc)
)
fetch first row with ties
对于此查询,您需要在select *
from mytable t
where
t.sweetness_score = (
select max(t1.sweetness_score)
from mytable t1
where t1.bakery = t.bakery
)
or t.created_timestamp = (
select max(t1.created_timestamp)
from mytable t1
where t1.bakery = t.bakery
)
和(bakery,sweetness_score)
上建立索引。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。