【问题标题】:Full outer join missing values with null完全外连接缺失值为 null
【发布时间】:2018-03-27 09:07:48
【问题描述】:

我正在尝试在 postgresql 数据库上使用 full outer join 来获取具有缺失行的空值的表的联合。但是,它对我不起作用。

示例如下:

create temp table nutrient_names (
    name text
);

insert into nutrient_names values
('fat'),
('sugar'),
('sodium'),
('total fat');

create temp table nutrients (
    food_id int,
    name text,
    quantity float8
);

insert into nutrients values
(1, 'fat', 0.3),
(1, 'sugar', 15),
(1, 'sodium', 10),
(1, 'total fat', 25),
(2, 'sugar', 10),
(2, 'sodium', 4);

这是输出:

select n.name, n.food_id, n.quantity from nutrient_names nn
full outer join nutrients n
on nn.name = n.name
order by n.food_id, n.name;

+---------------------------------+
|name           |food_id |quantity|
+---------------------------------+
|    'fat'      |1       |'0.3'   |
|    'sodium'   |1       |'10'    |
|    'sugar'    |1       |'15'    |
|    'total fat'|1       |'25'    |
|    'sodium'   |2       |'4'     |
|    'sugar'    |2       |'10'    |
+---------------------------------+

我想要什么:

+---------------------------------+
|name           |food_id |quantity|
+---------------------------------+
|    'fat'      |1       |'0.3'   |
|    'sodium'   |1       |'10'    |
|    'sugar'    |1       |'15'    |
|    'total fat'|1       |'25'    |
|    'fat'      |2       |null    | <----
|    'sodium'   |2       |'4'     |
|    'sugar'    |2       |'10'    |
|    'total fat'|2       |null    | <----
+---------------------------------+

【问题讨论】:

    标签: sql postgresql outer-join


    【解决方案1】:

    如果您有 2 个表(t1 和 t2),其列是:dimension_1、dimension_2、measure_1、measure_2

    你可以写

    select dimension_1, dimension_2, sum(measure_1) as measure_1, sum(measure_2) as measure_2
    from t1
    full join t2 using(dimension_1, dimension_2)
    group by dimension_1, dimension_2
    

    【讨论】:

      【解决方案2】:

      这里看起来不像FULL JOIN 适合。根据您的示例,您希望列出来自nutrient_names 的所有行的次数与您拥有食物 ID 的次数一样多。这通常使用CROSS JOIN 完成。

      如果您没有包含食物 ID 列表的单独表格,您可以即时构建它,然后加入它:

      WITH
      CTE_IDs
      AS
      (
          SELECT DISTINCT
              food_id
          FROM nutrients
      )
      SELECT
          nutrient_names.name
          ,CTE_IDs.food_id
          ,nutrients.quantity
      FROM
          CTE_IDs
          CROSS JOIN nutrient_names
          LEFT JOIN nutrients 
              ON  nutrients.name = nutrient_names.name
              AND nutrients.food_id = CTE_IDs.food_id
      ;
      

      【讨论】:

      • 就是这样。太感谢了。真是个问题!
      【解决方案3】:

      我建议有两张表格代表营养类型和食物类型。然后有一个额外的表格来说明营养价值。

      您可以对食物和营养进行交叉连接,然后对营养值进行左连接以获得结果。

      我做了一个小提琴给你看这里http://sqlfiddle.com/#!17/d974b/3

      您不能进行完全外部联接的原因是,如果您在一行上有数量,那么您也有 id。它们在同一个数据集中。

      【讨论】:

      • 将食物作为单独的餐桌可能还有其他好处。如果您想添加更多属性,如 food_type、weight 等,您不想将其存储在每个重复的行中
      猜你喜欢
      • 2019-03-08
      • 1970-01-01
      • 2021-08-27
      • 2012-01-06
      • 2013-03-11
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      相关资源
      最近更新 更多