如何根据 ID 合并行

How do merge rows based on IDs

我有两个 table,一个是这种结构:

id | user_id | field_type_id | value
-------------------------------------
1  | 1       | 1             | John Doe
2  | 1       | 2             | 0800 111 222
3  | 1       | 3             | johndoe@aol.comm
4  | 2       | 1             | Alice Cooper
5  | 2       | 2             | 0800 222 333
6  | 3       | 1             | Ben Sparks
7  | 3       | 3             | ben@gmail.com

我还有另一个 table 字段类型 ID:

field_type_id | name
-----------------------------
1             | Name
2             | Phone Number
3             | Email Address

什么样的查询可以运行得到如下输出:

user_id | name         | phone        | email
--------------------------------------------------
1       | John Doe     | 0800 111 222 | Johndoe@aol.com
2       | Alice Cooper | 0800 222 333 | NULL
3       | Ben Sparks   | NULL         | ben@gmail.com

假设 user_id 是唯一的(否则会抛出一个 DISTINCT),您可以根据第一个 table 上的用户 ID 进行分组,然后将其与每种类型的自身结合起来。它看起来像这样

WITH UniqueUsers AS (SELECT user_id FROM table1 GROUP BY user_id)
 
SELECT UniqueUsers.user_id,
  names.value AS name,
  phone.value AS phone,
  email.value AS email
FROM UniqueUsers
LEFT JOIN table1 AS names ON UniqueUsers.user_id = names.user_id AND names.field_type_id = 1
LEFT JOIN table1 AS phone ON UniqueUsers.user_id = phone.user_id AND phone.field_type_id = 2
LEFT JOIN table1 AS email ON UniqueUsers.user_id = email.user_id AND email.field_type_id = 3

您可以 join,并使用条件聚合进行透视:

select a.user_id
    max(a.value) filter(where f.name = 'name')  as name,
    max(a.value) filter(where f.name = 'phone') as phone,
    max(a.value) filter(where f.name = 'email') as email
from attributes a
inner join fieldtypes f on f.field_type_id = a.field_type_id
group by userid