[英]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 thre
列one, 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
因此,对于上表,当前查询将返回结果,因为此因为
b
是attribute=one
的Max
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.