如何按条件(枢轴)分隔列值以填充一行

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