【问题标题】:Postgresql vlookupPostgresql vlookup
【发布时间】:2009-07-16 20:57:37
【问题描述】:

假设我有一个包含以下列的“uservalue”表:

integer user_id
integer group_id
integer value

我可以很容易地得到每个组的最大值:

select max(value) from uservalue group by group_id;

我希望它返回每个组中具有最高值的 user_id。 matlab中的max函数也会返回最大值的索引,有没有办法让postgresql做同样的事情?

【问题讨论】:

    标签: postgresql greatest-n-per-group max vlookup


    【解决方案1】:

    执行此操作的正确方法是使用子查询。

    select 
        u.user_id,
        u.value 
    from 
         uservalue u
    join
        (select groupid, max(value) as max_value from uservalue group by group_id) mv
        on u.value = mv.max_value and mv.group_id = u.group_id
    

    但我有时更喜欢更简单的 hack。

    select max(value*100000 + user_id) - 100000, max(value) from user_value group by group_id
    

    确保数字 (100000) 高于您期望的任何用户 ID。这样可以确保在相同的值上只选择一个 user_id,而另一个同时选择它们。

    【讨论】:

    • 请注意,如果有多个用户具有相同的值,这将为每个组返回多行。
    • 第二个查询只返回一个,但第一个返回全部。就像我上一句说的那样。
    【解决方案2】:

    似乎您应该能够使用窗口查询来做到这一点,例如:

    SELECT DISTINCT 
      group_id,
      first_value(user_id) OVER w AS user,
      first_value(value) OVER w AS val
    FROM
      uservalue
     WINDOW w AS (PARTITION BY group_id ORDER BY value DESC)
    

    如果您有多个具有相同值的用户,此查询也将起作用(除非您将第二列添加到 ORDER BY,但您将不知道您将返回哪一列 - 但每个组只能返回一行)

    【讨论】:

    • window 函数刚刚在 postgress 中出现并且非常棒。但是,除非您使用的是最新版本,否则您会有点卡住。
    • 是的。这意味着还有另一个很好的升级理由 :-)
    【解决方案3】:

    【讨论】:

    • 咦,怎么这个问题还是被撞到了?
    猜你喜欢
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 2016-11-04
    相关资源
    最近更新 更多