Postregsql根据列值将一个检索到的记录转换为两个记录

问题描述

我有两个Postgresql表:

Searches:
+----+------------+-----------+-----------+
| id | patient_id | status_a  | status_b  |
+----+------------+-----------+-----------+
| 1  | 1          | Added     | Added     |
+----+------------+-----------+-----------+
| 2  | 2          | Added     | NULL      |
+----+------------+-----------+-----------+

Patients:
+----+------+---------+
| id | name | country |
+----+------+---------+
| 1  | John | England |
+----+------+---------+
| 2  | Tim  | France  |
+----+------+---------+

我想检索“将status_astatus_b设置为“已添加”的所有患者,根据状态列的值创建不同的记录”。

我需要能够实现这一目标:

+------------+------+---------+-----------+-----------+
| patient_id | name | country | status_a  | status_b  |
+------------+------+---------+-----------+-----------+
| 1          | John | England | Added     | NULL      |
+------------+------+---------+-----------+-----------+
| 1          | John | England | Null      | Added     |
+------------+------+---------+-----------+-----------+
| 2          | Tim  | France  | Added     | NULL      |
+------------+------+---------+-----------+-----------+

或者,甚至更好:

+------------+------+---------+-----------+
| patient_id | name | country | status    |
+------------+------+---------+-----------+
| 1          | John | England | A         |
+------------+------+---------+-----------+
| 1          | John | England | B         |
+------------+------+---------+-----------+
| 2          | Tim  | France  | A         |
+------------+------+---------+-----------+

解决方案吗?

解决方法

您需要使用searchesunion表透视成行。

select p.id as patient_id,p.name,p.country,s.status
  from patients p
       join (select patient_id,'A' as status
               from searches
              where status_a is not null
             union
             select patient_id,'B' as status
               from searches
              where status_b is not null) as s
         on s.patient_id = p.id
 order by p.id,s.status;
,

我建议使用横向连接:

select s.patient_id,v.status_a,v.status_b
from searches s cross join lateral
     (values (status_a,null),(null,status_b)
     ) v(status_a,status_b) join
     patients p
     on p.id = s.patient_id
where v.status_a is not null or v.status_b is not null;