(Ниже приводится весьма упрощенное описание моей проблемы политика компании не позволяет мне описать реальную ситуацию в деталях.).Postgres запрос массива
таблиц БД, участвующих являются:
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
Обратите внимание, что местоположения напрямую не связаны с продуктами, а только категории. Клиент должен иметь возможность видеть список местоположений, которые могут предоставить все категории продуктов, к которым принадлежат продукты, которые они хотят купить. Так, например:
Клиент хочет купить Ferrari. Это будет доступно из магазинов в категориях 10 или 30. Это дает нам магазины 100, 300 и 400, но не 200.
Однако, если клиент хочет купить Volvo и Lamborghini, это будет доступно из магазинов в категориях 10 и 20. Что только дает нам магазин 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);
Надеюсь, мое описание имеет смысл.
Здесь не нужны массивы, вы можете сделать все это, умножив соединения таблиц. –
Я продумал эти строки, но не смог собрать их вместе. Не могли бы вы помочь мне с более подробной информацией? –
Несомненно, если вы поместите свои данные образца в http://sqlfiddle.com/, я отдам его. –