从数据透视表中的另一个列值过滤 varchar 列
Filter varchar col from another col value in pivot
我有一个 table 如下所示:
object_key
created_by
updated_on
updated_by
attr_type
value_name
value_num
1
user1
3/21/2021
user1
name
John
1
user4
4/15/2021
user3
mobile_number
4567865
1
user3
4/21/2021
user2
office_number
2378783
我正在尝试使用查询进行数据透视:
SELECT object_key,
max(created_on) AS created_on,
max(updated_on) AS updated_on,
max(updated_by) FILTER (WHERE updated_on = max(updated_on)) AS updated_by,
max(array_to_string(value_name, '||'::text)) FILTER (WHERE attr_type = 'name' )as name,
max(array_to_string(value_num, '||'::text)) FILTER (WHERE attr_type = 'mobile_number') AS mobile_number,
max(array_to_string(value_num, '||'::text)) FILTER (WHERE attr_type = 'office_number') AS office_number
FROM object_attributes
GROUP BY object_key;
旋转 table 必须像:
object_key
created_by
updated_on
updated_by
name
mobile_number
office_number
1
user1
4/21/2021
user2
John
4567865
2378783
updated_by
应该来自每个 object_key
.
具有最高 updated_on
日期的行
但是 FILTER (WHERE updated_on = max(updated_on))
在查询中不起作用。
有没有办法 select updated_by
使用枢轴中的 updated_on
?
一种方法是使用 window 函数 first_value
:
SELECT
object_key,
max(created_on) AS created_on,
max(updated_on) AS updated_on,
first_value(updated_by) over(order updated_on desc) AS updated_by,
max(array_to_string(value_name,'||')) FILTER (WHERE attr_type = 'name' )as name,
max(array_to_string(value_num, '||')) FILTER (WHERE attr_type = 'mobile_number') AS mobile_number,
max(array_to_string(value_num, '||')) FILTER (WHERE attr_type = 'office_number') AS office_number
FROM object_attributes
GROUP BY object_key;
可以通过单个 SELECT
将 window 函数与 DISTINCT ON
相结合来实现:
改编为 table 最终在 your fiddle 中披露的定义:
SELECT DISTINCT ON (object_key)
object_key
, first_value(created_by) OVER w AS created_by
, updated_on
, updated_by
, min(array_to_string(value_name, '||')) FILTER (WHERE attr_type = 'Name' ) OVER w AS "Name"
, min(array_to_string(value_num , '||')) FILTER (WHERE attr_type = 'Mobile_number') OVER w AS "Mobile_number"
, min(array_to_string(value_num , '||')) FILTER (WHERE attr_type = 'Office_number') OVER w AS "Office_number"
-- , min(array_to_string(value_name, '||')) FILTER (WHERE attr_type = 'status' ) OVER w AS status -- ??
FROM object_attributes
WHERE object_key IN (1,2)
WINDOW w AS (PARTITION BY object_key ORDER BY updated_on)
ORDER BY object_key, updated_on DESC NULLS LAST;
db<>fiddle here
这行得通,因为 DISTINCT ON
在 window 函数之后应用。考虑 SELECT
查询中的事件序列:
- Best way to get result count before LIMIT was applied
我们可以在聚合 window 函数中使用 FILTER
子句。参见:
- Conditional lead/lag function PostgreSQL?
为了缩短代码,WINDOW
子句是可选的,您也可以将其拼写为 our 4x,结果相同。
为什么你可能需要 NULLS LAST
:
- Sort by column ASC, but NULL values first?
相关:
- Get values from first and last row per group
- Select first row in each GROUP BY group?
我有一个 table 如下所示:
object_key | created_by | updated_on | updated_by | attr_type | value_name | value_num |
---|---|---|---|---|---|---|
1 | user1 | 3/21/2021 | user1 | name | John | |
1 | user4 | 4/15/2021 | user3 | mobile_number | 4567865 | |
1 | user3 | 4/21/2021 | user2 | office_number | 2378783 |
我正在尝试使用查询进行数据透视:
SELECT object_key,
max(created_on) AS created_on,
max(updated_on) AS updated_on,
max(updated_by) FILTER (WHERE updated_on = max(updated_on)) AS updated_by,
max(array_to_string(value_name, '||'::text)) FILTER (WHERE attr_type = 'name' )as name,
max(array_to_string(value_num, '||'::text)) FILTER (WHERE attr_type = 'mobile_number') AS mobile_number,
max(array_to_string(value_num, '||'::text)) FILTER (WHERE attr_type = 'office_number') AS office_number
FROM object_attributes
GROUP BY object_key;
旋转 table 必须像:
object_key | created_by | updated_on | updated_by | name | mobile_number | office_number |
---|---|---|---|---|---|---|
1 | user1 | 4/21/2021 | user2 | John | 4567865 | 2378783 |
updated_by
应该来自每个 object_key
.
updated_on
日期的行
但是 FILTER (WHERE updated_on = max(updated_on))
在查询中不起作用。
有没有办法 select updated_by
使用枢轴中的 updated_on
?
一种方法是使用 window 函数 first_value
:
SELECT
object_key,
max(created_on) AS created_on,
max(updated_on) AS updated_on,
first_value(updated_by) over(order updated_on desc) AS updated_by,
max(array_to_string(value_name,'||')) FILTER (WHERE attr_type = 'name' )as name,
max(array_to_string(value_num, '||')) FILTER (WHERE attr_type = 'mobile_number') AS mobile_number,
max(array_to_string(value_num, '||')) FILTER (WHERE attr_type = 'office_number') AS office_number
FROM object_attributes
GROUP BY object_key;
可以通过单个 SELECT
将 window 函数与 DISTINCT ON
相结合来实现:
改编为 table 最终在 your fiddle 中披露的定义:
SELECT DISTINCT ON (object_key)
object_key
, first_value(created_by) OVER w AS created_by
, updated_on
, updated_by
, min(array_to_string(value_name, '||')) FILTER (WHERE attr_type = 'Name' ) OVER w AS "Name"
, min(array_to_string(value_num , '||')) FILTER (WHERE attr_type = 'Mobile_number') OVER w AS "Mobile_number"
, min(array_to_string(value_num , '||')) FILTER (WHERE attr_type = 'Office_number') OVER w AS "Office_number"
-- , min(array_to_string(value_name, '||')) FILTER (WHERE attr_type = 'status' ) OVER w AS status -- ??
FROM object_attributes
WHERE object_key IN (1,2)
WINDOW w AS (PARTITION BY object_key ORDER BY updated_on)
ORDER BY object_key, updated_on DESC NULLS LAST;
db<>fiddle here
这行得通,因为 DISTINCT ON
在 window 函数之后应用。考虑 SELECT
查询中的事件序列:
- Best way to get result count before LIMIT was applied
我们可以在聚合 window 函数中使用 FILTER
子句。参见:
- Conditional lead/lag function PostgreSQL?
为了缩短代码,WINDOW
子句是可选的,您也可以将其拼写为 our 4x,结果相同。
为什么你可能需要 NULLS LAST
:
- Sort by column ASC, but NULL values first?
相关:
- Get values from first and last row per group
- Select first row in each GROUP BY group?