I have a problem getting all the records from a table, even if there is no relationship. My first table (warehouse) has a warehouse type, which is a foreign key from another table. There is another table that contains all the types of products that can exist in the different warehouses, and they are defined based on the type of warehouse (my relation table between types of warehouse and types of products). My goal is to obtain all the types of products, indicating which ones are assigned to the warehouse based on its type and which ones are not.
I have tried my query in different ways: with UNION, subqueries but I do not achieve my goal. I include the fiddle with the query that is closest to the expected result:
SELECT DISTINCT w.id, w.name, wht.type AS whouse_type, APT.product_type_id, APT.product_type,
CASE
WHEN w.type_id = APT.warehouse_type_id
THEN "YES"
WHEN w.type_id <> APT.warehouse_type_id
THEN "NO"
WHEN APT.warehouse_type_id IS NULL
THEN "NO"
ELSE NULL
END AS assigned
FROM warehouse w
LEFT JOIN warehouse_types wht ON w.type_id = wht.id
CROSS JOIN (
SELECT DISTINCT pt.id AS product_type_id, pt.product_type, rel.warehouse_type_id
FROM product_types pt
LEFT JOIN products_type_by_wh_types rel ON pt.id = rel.product_type_id
) AS APT -- all products types
where w.id = 1
ORDER BY w.name, APT.product_type_id, type_of_warehouse;
This gave me:
+----+-------------+-------+--------------+----------+
| id | whouse_type | pt_id | product_type | assigned |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 1 | Industry | YES |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 1 | Industry | NO |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 2 | Transport | NO |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 3 | Chemicals | NO |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 4 | Food and B | YES |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 4 | Food and B | NO |
+----+-------------+-------+--------------+----------+
And the expect result should be:
+----+-------------+-------+--------------+----------+
| id | whouse_type | pt_id | product_type | assigned |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 1 | Industry | YES |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 2 | Transport | NO |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 3 | Chemicals | NO |
+----+-------------+-------+--------------+----------+
| 1 | NORTH | 4 | Food and B | YES |
+----+-------------+-------+--------------+----------+
As @Barmar suggested (once again, thank you!) the solution is adding a GROUP BY and make use of the MAX function for my CASE. This is the final query:
SELECT DISTINCT w.id, w.name, wht.type AS whouse_type, APT.product_type_id, APT.product_type,
MAX(CASE
WHEN w.type_id = APT.warehouse_type_id
THEN 1
WHEN w.type_id <> APT.warehouse_type_id
THEN 0
WHEN APT.warehouse_type_id IS NULL
THEN 0
ELSE NULL
END) AS assigned
FROM warehouse w
LEFT JOIN warehouse_types wht ON w.type_id = wht.id
CROSS JOIN (
SELECT DISTINCT pt.id AS product_type_id, pt.product_type, rel.warehouse_type_id
FROM product_types pt
LEFT JOIN products_type_by_wh_types rel ON pt.id = rel.product_type_id
) AS APT -- all products types
GROUP BY w.id, APT.product_type_id
ORDER BY w.name, APT.product_type_id, assigned;