(The following is a very simplified description of my problem. The company policy does not allow me to describe the real scenario in detail.)
Used DB tables:
PRODUCTS:
ID Name
---------
1 Ferrari
2 Lamborghini
3 Volvo
CATEGORIES:
ID Name
----------
10 Sports cars
20 Safe cars
30 Red cars
PRODUCTS_CATEGORIES
ProductID CategoryID
-----------------------
1 10
1 30
2 10
3 20
LOCATIONS:
ID Name
------------
100 Sports car store
200 Safe car store
300 Red car store
400 All cars r us
LOCATIONS_CATEGORIES:
LocationID CategoryID
------------------------
100 10
200 20
300 30
400 10
400 20
400 30
Please note that locations are not directly related to products, only categories. The customer should be able to see a list of locations that can provide all categories of products to which the products they want to buy belong. So for example:
A customer wants to buy a Ferrari. It will be available from stores in categories 10 or 30. This gives us stores of 100, 300 and 400, but not 200.
However, if a customer wants to buy Volvo and Lamborghini, it will be available from stores in categories 10 and 20. What only gives us store 400.
Ferrari Volvo. 10 + 20 ( ) 30 + 20 ( ).
postgres, , . < @, . SQL, , Ferrari Lamborghini. , , , . 400, 400 100.
SELECT l.* FROM locations l
WHERE
(SELECT array_agg(DISTINCT(categoryid)) FROM products_categories WHERE productid IN (1,2))
<@
(SELECT array_agg(categoryid) FROM locations_categories WHERE locationid = l.id);
, .