【问题标题】:PostgreSQL - Select row with composite maximum value from 2 columnsPostgreSQL - 从 2 列中选择具有复合最大值的行
【发布时间】:2018-05-30 08:45:57
【问题描述】:

我想根据一些简单的规则在 PostgreSQL 9.6 中为商家选择最优惠的价格:

  • 无论福利类型如何,如果折扣值更大,则优惠会比其他优惠更好
  • 如果折扣值相等,则福利类型为 ALL 的人会击败福利类型为 FOOD 的人
  • 如果折扣和福利类型相同,则可以选择任何优惠,例如选择第一个

所以最好的不仅仅是一个 max() 调用,而是一个“有条件的” max(),其中也应该检查另一列以确定它是哪一行。

你能帮忙吗?

架构:

create table offer (
    id bigserial not null,
    discount int4,
    benefit_type varchar(25),
    ...
    merchant_id int8 not null
);

查询(部分):

select merchant_id, max(discount) as max_discount
from offer
group by merchant_id;

数据库中的示例报价:

id  discount    benefit_type    ... merchant_id
0   10          FOOD                0
1   20          FOOD                0
2   20          ALL                 0
3   30          ALL                 1
4   40          ALL                 1
5   40          FOOD                1
6   40          ALL                 2
7   50          FOOD                2

想要的结果集:

merchant_id     max_discount    benefit_type
0               20              ALL
1               40              ALL
2               50              FOOD
  • 商家 0 的最佳报价是报价 2,因为 20 ALL > 20 FOOD。
  • 商家 1 的最佳报价是报价 4,因为 40 ALL > 30 ALL。
  • 商家 2 的最佳报价是报价 5,因为 50 FOOD > 40 ALL。

【问题讨论】:

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


    【解决方案1】:

    这可以使用distinct on() 和一个自定义的benefit_type 排序定义来实现:

    select distinct on (merchant_id) *
    from offer
    order by merchant_id, 
             discount desc, 
             case when benefit_type = 'ALL' then 1 else 2 end;
    

    这更喜欢更高的折扣。如果两个折扣相同,则使用 ALL 的好处类型作为决胜局。

    在线示例:http://rextester.com/TFBP17217

    【讨论】:

    • 注:第三个条件可以简化为(benefit_type = 'All')::int desc
    猜你喜欢
    • 2018-10-06
    • 2018-12-16
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    相关资源
    最近更新 更多