【问题标题】:Get max record and min record together via MySQL通过 MySQL 一起获取最大记录和最小记录
【发布时间】:2020-09-09 00:47:19
【问题描述】:

拥有这样的数据集:

id inv value
1  1   10
1  2   12
1  3   4
2  1   20
2  2   2

如何编写SQL获取数据集,对于每个id,使用min inv记录减去max inv记录的值数据,数据集如下所示:

id delta_value min_inv max_inv
1    6           1       3
2    18          1       2

请注意,max inv 的值并不一定意味着最大值。

【问题讨论】:

  • 如果您告诉我们您的表名和列类型会有所帮助;最好的方法是只显示show create table yourtablename 的输出(作为文本,而不是图像)。还有,什么mysql版本?
  • 请在此处了解如何提问。 stackoverflow.com/help/how-to-ask

标签: mysql sql


【解决方案1】:
select id, delta_value, min(inv) min_inv, max(inv) max_inv
from (
    select
        id,
        first_value(value) over (partition by id order by inv)
        - first_value(value) over (partition by id order by inv desc) delta_value,
        inv
    from foo
) foo group by id, delta_value;

【讨论】:

  • 我要补充一点,这只适用于 MySQL 8+,因为它是引入窗口函数的版本! +1。
  • 错误:delta_value 必须是聚合表达式或出现在 GROUP BY 子句中
  • @hongchangfirst 啊,加群了。如果您设置了 ONLY_FULL_GROUP_BY sql 模式,则需要这样做
【解决方案2】:

您需要创建集合的子集以获得所需的值,这是 Mysql

select imm.id, 
       tmin.value-tmax.value as delta_value,
       imm.min_inv,
       imm.max_inv
  from (select id, 
               min(inv) min_inv, 
               max(inv) max_inv 
          from yourTable 
         group by id) imm 
        inner join yourTable tmin on tmin.id = imm.id
                                    and tmin.inv = imm.min_inv
        inner join yourTable tmax on tmax.id = imm.id
                                    and tmax.inv = imm.max_inv
         

在这里查看它的工作原理:http://sqlfiddle.com/#!9/88a4d6/2

【讨论】:

    【解决方案3】:

    如果inv 总是从1 开始,那么就会想到条件聚合:

    select id,
           sum(case when inv = max_inv then value
                    when inv = 1 then - value
               end),
           min(inv), max(inv)
    from (select t.*,
                 max(inv) over (partition by id) as max_inv
          from t
         ) t
    group by id;
    

    您甚至可以在没有子查询的情况下执行此操作(尽管性能可能不会更好):

    select distinct id,
           (first_value(value) over (partition by id order by inv desc) -
            first_value(value) over (partition by id order by inv asc)
           ) as diff,
           min(inv) over (partition by id),
           max(inv) over (partition by id)
            
    from t;
    

    【讨论】:

      【解决方案4】:

      假设您的 MySQL 版本支持 window functions,您可以根据每个 id 匹配的 maxmin inv 来选择每个 id 的 maxmin 值。这尤其适用于每个 inv 的每个 id 有多个值

      select id, 
             max(value)-min(value) as delta_value,
             max(inv) as max_inv, 
             min(inv) as min_inv
      from (select id, 
                   inv, 
                   case when inv = max(inv) over (partition by id) 
                          or inv = min(inv) over (partition by id) then value  end as value
                 from your_table) t
      group by id;
      

      DEMO

      【讨论】:

        猜你喜欢
        • 2012-12-14
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 2019-12-28
        相关资源
        最近更新 更多