Reputation: 2917
In MySQL 5.7.32 I want to retrieve all products from a product table with prices for those products from multiple shops if they are available, if they are not available NULL should be returned for the missing price at that shop.
There are three tables: products, prices, shops
Tables:
-- table shops
id | name
1 | amazon
2 | ebay
3 | craigslist
-- table products
ARTICLE_ID | name
123 | article 1
124 | article 2
125 | article 3
-- table prices
DATE | SHOP_ID | ARTICLE_ID | PRICE
201220 | 1 | 123 | 12.99
201220 | 2 | 123 | 9.99
201220 | 1 | 124 | 10.80
201221 | 1 | 123 | 13.99
-- Desired result
SHOP | PRODUCT | PRICE
amazon | 123 | 12.99
amazon | 124 | 10.80
amazon | 125 | NULL
ebay | 123 | 9.99
ebay | 124 | NULL
ebay | 125 | NULL
SQL:
SELECT
s.name,
p.id,
mps.price
FROM
shops s,
products p
LEFT JOIN prices mps ON p.ARTICLE_ID = mps.ARTICLE_ID AND mps.DATE = 20201220
WHERE
s.ID IN ( '1' , '2')
I could not figure out how to show one line per product and shop. Is this even possible with that table setup or do I need to change my database structure?
Upvotes: 1
Views: 37
Reputation: 164099
In the ON
clause you must also define the link between shops
and prices
:
SELECT
s.name,
p.ARTICLE_ID,
mps.price
FROM
shops s CROSS JOIN products p
LEFT JOIN prices mps
ON s.id = mps.shop_id AND p.ARTICLE_ID = mps.ARTICLE_ID AND mps.DATE = 201220
WHERE
s.ID IN ( '1' , '2')
ORDER BY s.name, p.ARTICLE_ID
See the demo.
Results:
> name | ARTICLE_ID | price
> :----- | ---------: | ----:
> amazon | 123 | 12.99
> amazon | 124 | 10.8
> amazon | 125 | null
> ebay | 123 | 9.99
> ebay | 124 | null
> ebay | 125 | null
Upvotes: 2