I'm trying to use full outer join
on postgresql database to get a union of tables that has null values for the missing rows. However, it is not working for me.
Here is the example:
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);
Here is the output:
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' |
+---------------------------------+
What I want:
+---------------------------------+
|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 | <----
+---------------------------------+
I suggest having two tables representing nutrition types and types of food. Then have an extra table specifying the nutrition values.
You can do a cross join on food and nutritions and then do a left join on the nutrition values to get your results.
I made a fiddle for you to look at here http://sqlfiddle.com/#!17/d974b/3
The reason that you cannot do a full outer join is that if you have the quantity on a row you have the id aswell. They are in the same dataset.
It doesn't look like FULL JOIN
suits here. Based on your example you want to list all rows from nutrient_names
as many times as you have food IDs. This is usually done with CROSS JOIN
.
If you don't have a separate table with the list of food IDs, you can build it on the fly and then join to it:
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
;
if you have 2 tables (t1 and t2) with cols: dimension_1, dimension_2, measure_1, measure_2
you can write
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.