I have a table like this, let's call it main
| location | item | price |
|---|---|---|
| l1 | item1 | 3.00 |
| l1 | item2 | 1.00 |
| l2 | item1 | 3.00 |
| l2 | item2 | 1.50 |
| l2 | item3 | 2.00 |
| l3 | item4 | 5.00 |
| l3 | item5 | 5.00 |
and a separate table, call it items
| items |
|---|
| item 1 |
| item 2 |
| item 3 |
| item 5 |
| item 4 |
| item 5 |
| item 6 |
and am currently trying to join the two together with this
with main as (subquery to create main),
items as (select distinct items from main)
select i.items, m.*
from items i left join main m
on i.items = m.items
order by m.location, i.items
and my desired result is
| i.items | location | item | price |
|---|---|---|---|
| item1 | l1 | item1 | 3.00 |
| item2 | l1 | item2 | 1.00 |
| item3 | l1 | null | null |
| item4 | l1 | null | null |
| item5 | l1 | null | null |
| item6 | l1 | null | null |
| item1 | l2 | item1 | 3.00 |
| item2 | l2 | item2 | 1.50 |
| item3 | l2 | item3 | 2.00 |
| item4 | l2 | null | null |
| item5 | l2 | null | null |
| item6 | l2 | null | null |
| item1 | l3 | null | null |
| item2 | l3 | null | null |
| item3 | l3 | null | null |
| item4 | l3 | item4 | 5.00 |
| item5 | l3 | item5 | 5.00 |
| item6 | l3 | null | null |
However, it ends up just looking like the main table but sorted, with none of the unmatched items being shown. Am I doing something wrong?
CodePudding user response:
It seems you want one result row per item and location whether or not that pair has entries in the main table. So first generate these rows with a cross join. Only then outer join your original data.
with main as (<subquery to create main>),
items as (select distinct item from main),
locations as (select distinct location from main)
select i.item, l.location, m.price
from items i
cross join locations l
left join main m on m.item = i.item and m.location = l.location
order by i.item, l.location;
