简体   繁体   English

根据其他列从不同列获取最新值

[英]Getting latest values from different columns based on other column

So I've a query like this所以我有一个这样的查询

select 
  user_id,
  MAX(
    case when attribute = 'one' then newValue else 'No Update' end
  ) as one,
  MAX(
    case when attribute = 'two' then newValue else 'No Update' end
  ) as two,
  MAX(
    case when attribute = 'thre' then newValue else 'No Update' end
  ) as thre,
from table
group by user_id

This query returns result as max value for that particular attribute value in different column.此查询将结果作为不同列中该特定属性值的最大值返回。

There is an updated_at column too in this table.此表中也有一个updated_at列。 Now instead of this, I want that the returned column should contain the latest value according to that updated_at field.现在而不是这个,我希望返回的列应该包含根据该 updated_at 字段的最新值。

So basically the column one, two and thre should either contain latest values according to updated_at field.所以基本上第一列one, two and threone, two and thre第三列应该包含根据updated_at字段的最新值。 If no values are there, then the column should contain No Update string.如果没有值,则该列应包含No Update字符串。

What could be the right way?什么是正确的方法?

Example例子

user_id | attribute | newValue | updatedAt
1       | one       | null     | 2018-01-20
1       | one       | b        | 2018-01-21
1       | one       | a        | 2018-01-22
1       | two       | null     | 2018-01-23
1       | two       | null     | 2018-01-24
1       | two       | null     | 2018-01-25

So for above table the current query would return result as this coz b is the Max value for attribute=one因此,对于上表,当前查询将返回结果,因为此因为battribute=oneMax

user_id | one | two 
    1   | b   | No Update

But I want the result of column one to be latest one according to updatedAt column like this但我想列的结果one是最新的一个根据updatedAt喜欢此列

user_id | one | two 
    1   | a   | No Update

First use DISTINCT ON (user_id, attribute) to get the only the rows with the latest updatedAt for each attribute and then aggregate on the results:首先使用DISTINCT ON (user_id, attribute)获取每个attribute的唯一具有最新updatedAt的行,然后聚合结果:

select user_id,
       coalesce(max(case when attribute = 'one' then newvalue end), 'No Update') one,
       coalesce(max(case when attribute = 'two' then newvalue end), 'No Update') two
from (
  select distinct on (user_id, attribute) *
  from tablename
  order by user_id, attribute, updatedAt desc
) t 
group by user_id

See the demo .请参阅演示
Results:结果:

> user_id | one | two      
> ------: | :-- | :--------
>       1 | a   | No Update

Postgres doesn't have first and last aggregation functions, but you can get similar functionality using arrays: Postgres 没有 first 和 last 聚合函数,但您可以使用数组获得类似的功能:

select user_id,
       coalesce((array_agg(newvalue order by updatedAt desc) filter (where attribute = 'one'))[1], 'No update') as one,
       coalesce((array_agg(newvalue order by updatedAt desc) filter (where attribute = 'two'))[1], 'No update') as two
from t 
group by user_id;

Here is a db<>fiddle. 是一个 db<>fiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM