全外连接缺失值与 null
Full outer join missing values with null
我正在尝试在 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 | <----
+---------------------------------+
我建议用两个 table 代表营养类型和食物类型。然后有一个额外的 table 指定营养价值。
您可以对食物和营养进行交叉连接,然后对营养值进行左连接以获得结果。
我做了一个fiddle给你看这里http://sqlfiddle.com/#!17/d974b/3
您不能进行完全外部联接的原因是,如果您在一行中有数量,那么您也有 ID。他们在同一个数据集中。
看起来 FULL JOIN
不适合这里。根据您的示例,您希望列出 nutrient_names
中的所有行,次数与您拥有食物 ID 的次数一样多。这通常用 CROSS JOIN
.
完成
如果您没有单独的 table 食品 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
;
如果您有 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
我正在尝试在 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 | <----
+---------------------------------+
我建议用两个 table 代表营养类型和食物类型。然后有一个额外的 table 指定营养价值。
您可以对食物和营养进行交叉连接,然后对营养值进行左连接以获得结果。
我做了一个fiddle给你看这里http://sqlfiddle.com/#!17/d974b/3
您不能进行完全外部联接的原因是,如果您在一行中有数量,那么您也有 ID。他们在同一个数据集中。
看起来 FULL JOIN
不适合这里。根据您的示例,您希望列出 nutrient_names
中的所有行,次数与您拥有食物 ID 的次数一样多。这通常用 CROSS JOIN
.
如果您没有单独的 table 食品 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
;
如果您有 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