I have three tables:
- store
- article_to_store
- article table.
CREATE TABLE store ( `id` int(10) unsigned NOT NULL, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE article_to store ( `id` int(10) unsigned NOT NULL, `article_id` int(10) unsigned NOT NULL, `store_id` int(10) unsigned NOT NULL, `Price`...., PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE article ( `id` int(10) unsigned NOT NULL, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I need all articles with the store name. For all articles, I want to list all stores
store
table contains 3 stores.
article
table contains 2 articles.
article_to_store
relation table maybe has 2 records. One article in 2 stores.
I need a mysql query with this result:
store.name | article_to_store.id | article.name |
---|---|---|
Store 1 | 1 | Pen |
Store 2 | 2 | Pen |
Store 3 | null | Pen |
Store 1 | null | Erase |
Store 2 | null | Erase |
Store 3 | null | Erase |
SELECT store.name, article.name, article_to_store.id FROM store, article_to_store, article Group by store.id, article.id ORDER BY article.id, store.id
If I use simple join the article_to_store table always id = 1
If I use LEFT JOIN, don’t get the unmatched records.
When I remove the group by then I got 12 records.
3 stores * 2 article_to_store * 2 article = 12 record. Thats not good for me.
I would like to 3 stores * 2 article = 6 record with article_to store data if exist.
I tried many join types, but it doesn’t work. Thanks for any ideas.
Advertisement
Answer
You can use a cross join
to achieve this.
SELECT s.name, ats.id, a.name FROM article a CROSS JOIN store s LEFT JOIN article_to_store ats ON a.id = ats.article_id AND s.id = ats.store_id ORDER BY a.id, s.id
A bit of an unusual scenario, but here, you’re essentially asking “For every article, I want to list all stores – that’s a cross join
“. Then to get the middle column, you’re only sometimes expecting a row back, which is a left join
.