如何按条件(枢轴)分隔列值以填充一行
How to separate column values by condition (pivot) to fill one row
我有两个 table,我想做一个 full outer join
,其中生成的视图将值 table 分成两个单独的列,每个 [=13] 一行=].我用 CASE
表达式对 select 按类型进行了一种方法,然后将其与 pandas 一起使用以填充值和 return 不同的 name_ids.
姓名Table
name_id
name
1
foo
2
bar
3
doo
4
sue
值Table
name_id
value
type
1
90
red
2
95
blue
3
33
red
3
35
blue
4
60
blue
4
20
red
这是精简版。在我的完整 table 中,我需要使用按类型排序的两个单独的值 table 执行两次,red/blue 和 control/placebo.
简单加入
SELECT names_table.name_id, name, value, type
FULL OUTER JOIN values_table
ON names_table.name_id = values_table.name_id
WHERE type in ('red', 'blue')
name_id
name
value
type
1
foo
90
red
2
bar
95
blue
3
doo
33
red
3
doo
35
blue
4
sue
60
blue
4
sue
20
red
当前解决结果,然后我用 python 和 pandas
修复
SELECT names_table.name_id, name, value, type
CASE
WHEN type = 'red' THEN value END red,
CASE
WHEN type = 'blue' THEN value END blue
FROM names_table
FULL OUTER JOIN values_table
ON names_table.name_id = values_table.name_id
name_id
name
blue
red
1
foo
Null
90
2
bar
95
Null
3
doo
35
Null
3
doo
Null
33
4
sue
60
Null
4
sue
Null
20
下面是我想要的输出,其中我将类型作为列,而只有行用于唯一 name_ids,但值为 tables 1 和 2。
期望的输出
name_id
name
blue
red
1
foo
Null
90
2
bar
95
Null
3
doo
35
33
4
sue
60
20
I have two tables that I'd like do a full outer join
...
你为什么要这样做?更好地解释您实际想要做什么,而不是假设的工具来实现它。
使用聚合 FILTER
子句进行简单旋转。参见:
- Aggregate columns with additional (distinct) filters
SELECT name_id, n.name, v.blue, v.red
FROM (
SELECT name_id
, min(value) FILTER (WHERE type = 'blue') AS blue
, min(value) FILTER (WHERE type = 'red') AS red
FROM values_table
GROUP BY 1
) v
LEFT JOIN names_table n USING (name_id);
生成您想要的结果。
db<>fiddle here
即使未找到名称,LEFT JOIN
也会包含结果行。
FULL [OUTER] JOIN
会在结果中添加根本没有值的名称。我想你真的想要 LEFT [OUTER] JOIN
甚至是普通的 [INNER] JOIN
.
您可以切换 JOIN
类型以适应您的实际需求。相同的列名“name_id”允许与 USING
子句连接。外部 SELECT
中的非限定 name_id
适用于任何连接类型。
注意我是先聚合后加入的。通常要快得多。参见:
- Query with LEFT JOIN not returning rows for count of 0
如果“红色”或“蓝色”可能存在重复值,您必须定义如何处理这些值。
对于更复杂的查询,请考虑 crosstab()
。参见:
- PostgreSQL Crosstab Query
我有两个 table,我想做一个 full outer join
,其中生成的视图将值 table 分成两个单独的列,每个 [=13] 一行=].我用 CASE
表达式对 select 按类型进行了一种方法,然后将其与 pandas 一起使用以填充值和 return 不同的 name_ids.
姓名Table
name_id | name |
---|---|
1 | foo |
2 | bar |
3 | doo |
4 | sue |
值Table
name_id | value | type |
---|---|---|
1 | 90 | red |
2 | 95 | blue |
3 | 33 | red |
3 | 35 | blue |
4 | 60 | blue |
4 | 20 | red |
这是精简版。在我的完整 table 中,我需要使用按类型排序的两个单独的值 table 执行两次,red/blue 和 control/placebo.
简单加入
SELECT names_table.name_id, name, value, type
FULL OUTER JOIN values_table
ON names_table.name_id = values_table.name_id
WHERE type in ('red', 'blue')
name_id | name | value | type |
---|---|---|---|
1 | foo | 90 | red |
2 | bar | 95 | blue |
3 | doo | 33 | red |
3 | doo | 35 | blue |
4 | sue | 60 | blue |
4 | sue | 20 | red |
当前解决结果,然后我用 python 和 pandas
修复SELECT names_table.name_id, name, value, type
CASE
WHEN type = 'red' THEN value END red,
CASE
WHEN type = 'blue' THEN value END blue
FROM names_table
FULL OUTER JOIN values_table
ON names_table.name_id = values_table.name_id
name_id | name | blue | red |
---|---|---|---|
1 | foo | Null | 90 |
2 | bar | 95 | Null |
3 | doo | 35 | Null |
3 | doo | Null | 33 |
4 | sue | 60 | Null |
4 | sue | Null | 20 |
下面是我想要的输出,其中我将类型作为列,而只有行用于唯一 name_ids,但值为 tables 1 和 2。
期望的输出
name_id | name | blue | red |
---|---|---|---|
1 | foo | Null | 90 |
2 | bar | 95 | Null |
3 | doo | 35 | 33 |
4 | sue | 60 | 20 |
I have two tables that I'd like do a
full outer join
...
你为什么要这样做?更好地解释您实际想要做什么,而不是假设的工具来实现它。
使用聚合 FILTER
子句进行简单旋转。参见:
- Aggregate columns with additional (distinct) filters
SELECT name_id, n.name, v.blue, v.red
FROM (
SELECT name_id
, min(value) FILTER (WHERE type = 'blue') AS blue
, min(value) FILTER (WHERE type = 'red') AS red
FROM values_table
GROUP BY 1
) v
LEFT JOIN names_table n USING (name_id);
生成您想要的结果。
db<>fiddle here
即使未找到名称,LEFT JOIN
也会包含结果行。
FULL [OUTER] JOIN
会在结果中添加根本没有值的名称。我想你真的想要 LEFT [OUTER] JOIN
甚至是普通的 [INNER] JOIN
.
您可以切换 JOIN
类型以适应您的实际需求。相同的列名“name_id”允许与 USING
子句连接。外部 SELECT
中的非限定 name_id
适用于任何连接类型。
注意我是先聚合后加入的。通常要快得多。参见:
- Query with LEFT JOIN not returning rows for count of 0
如果“红色”或“蓝色”可能存在重复值,您必须定义如何处理这些值。
对于更复杂的查询,请考虑 crosstab()
。参见:
- PostgreSQL Crosstab Query