【问题标题】:SQL - return rows in partition based on max valueSQL - 根据最大​​值返回分区中的行
【发布时间】:2020-10-28 15:59:25
【问题描述】:

我有以下带有 cmets 的数据集,必须返回哪一行。

INSERT INTO rates
  (country,kg_from,kg_to,value)
VALUES
  --('pl', '0', '5', '2.5'),
  --('pl', '5', '10', '4.5'),
  --('pl', '10', '15', '6'),
  --('pl', '15', '20', '8'), -- return this row
  --('de', '0', '5', '1.5'),
  --('de', '5', '10', '1.5'),
  --('de', '10', '15', '1.5'),
  --('de', '15', '45', '1.5'),  -- return this row
  --('cz', '0', '5', '5'),
  --('cz', '5', '10', '5'),
  --('cz', '10', '15', '6'),
  --('cz', '15', '30', '4') -- return this row

逻辑是:返回每个国家分区内最大kg_to的值。

当前工作代码:

select t.country, t.kg_to, t.value
from rates t
inner join (select country, max(t2.kg_to) as max_kg
                      from rates t2
                      group by 1) t2 on t.country = t2.country
WHERE t.kg_to = t2.max_kg;
enter code here

问题:

  1. 更短的代码会更好,关于如何改进它的任何想法?

【问题讨论】:

  • Postgres 和 Snowflake 是不同的 SQL 产品。您真正使用的是哪个?

标签: sql postgresql snowflake-cloud-data-platform data-partitioning


【解决方案1】:

对于Snowflake,也可以避免窗口函数上的子查询,直接使用QUALIFY函数:

select r.*
from rates r
QUALIFY row_number() over (partition by country order by kg_to desc) = 1;

【讨论】:

  • 干净利落。不幸的是,Postgresql 中没有 QUALIFY 子句,WHERE 中也不允许使用窗口函数。
  • @Stefanov.sm OP 已经标记了 Snowflake。所以,我想我会分享。
  • 当然。很优雅。
  • 标记 postgre/snowflake 的原因是我的情况必须同时处理。
【解决方案2】:

使用distinct on:

select distinct on (t.country) r.*
from rates r
order by t.country, kg_to desc;

或窗口函数:

select r.*
from (select r.*,
             row_number() over (partition by country order by kg_to desc) as seqnum
      from rates r
     ) r
where seqnum = 1;

注意:我也看不出您的代码如何检索重复项,除非您的表中有一个国家/地区的重复最大值。

【讨论】:

    【解决方案3】:

    您需要 distinct on (t.country) 才能在每个国家/地区拥有一条记录。 order by 确定每个国家/地区选择哪一条记录。

    select distinct on (country)
        country, kg_to, value
     from rates
     order by country, kg_to desc;
    

    【讨论】:

    • 请注意,此语法不适用于 Snowflake。
    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 2020-08-12
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    相关资源
    最近更新 更多