I'm certain I'm going to be embarrassed by the eventual answer, but I've been googling around and banging my head against the wall and can't figure it out.
I have four tables described below. I'm trying to get the query that shows all the products related to users (through the user_products
table) AND all the categories.
Table definitions
CREATE TEMPORARY TABLE categories (
id INT PRIMARY KEY NOT NULL
, cat_name TEXT
);
CREATE TEMPORARY TABLE products (
id INT PRIMARY KEY NOT NULL
, category_id INT
, prod_name TEXT
);
CREATE TEMPORARY TABLE users (
id INT PRIMARY KEY NOT NULL
, user_name TEXT
);
CREATE TEMPORARY TABLE user_products (
id INT PRIMARY KEY NOT NULL
, product_id INT
, user_id INT
, quantity INT
);
INSERT statements
INSERT INTO categories VALUES (1, 'cat1')
,(2, 'cat2')
,(3, 'cat3')
,(4, 'cat4');
INSERT INTO products VALUES (1, 1, 'prod1')
,(2, 1, 'prod2')
,(3, 2, 'prod3')
,(4, 3, 'prod4')
,(5, 4, 'prod4');
INSERT INTO users VALUES (1, 'user1')
,(2, 'user2')
,(3, 'user3');
INSERT INTO user_products VALUES (1, 1, 1, 4)
,(2, 2, 1, 3)
,(3, 3, 1, 3)
,(4, 2, 2, 3)
,(5, 2, 2, 2)
,(6, 5, 2, 2);
I've tried several options, and this certainly feels like an outer join scenario. The most promising query THAT DOES NOT WORK is:
SELECT up.*, p.*, c.*, u.*
FROM user_products AS up
JOIN users AS u ON u.id = up.user_id
JOIN products AS p ON p.id = up.product_id
RIGHT OUTER JOIN categories AS c ON c.id = p.category_id
WHERE u.id = 1 OR u.id IS NULL
Result from above query
id | product_id | user_id | quantity | id | category_id | prod_name | id | cat_name | id | user_name
----+------------+---------+----------+----+-------------+-----------+----+----------+----+-----------
1 | 1 | 1 | 4 | 1 | 1 | prod1 | 1 | cat1 | 1 | user1
2 | 2 | 1 | 3 | 2 | 1 | prod2 | 1 | cat1 | 1 | user1
3 | 3 | 1 | 3 | 3 | 2 | prod3 | 2 | cat2 | 1 | user1
| | | | | | | 3 | cat3 | |
The reason it does not work is that it fails to return 'cat4' from the categories table. Obviously this is because the WHERE
clause is selecting it out of the result set. I'm at a loss to as to get a result set that includes all categories + the details of the products and quantities for which there are records in the specified user_products table.
The query should
- return all categories
- return data populated for user info iff the user has that product (a record exists in user_products)
- not return rows with other user ids