@Krechet

Как составить запрос?

Приветствую Вас, уважаемые хаброжители.
Однажды я задавал вопрос http://habrahabr.ru/qa/20390/ по оптимизации SQL-запроса (спасибо всем кто откликнулся).
Там необходимо было выбрать все объявления для устройства показа в которых нет категорий, отсутствующих в категориях устройства показа.

Теперь мне необходимо выбрать все устройства показа для конкретного объявления по такому же условию.
есть табличка devices_categories (deviceId, catId)
object_categories (objectId,categoryId)

Нужно для конкретного objectId выбрать те deviceId которые удовлетворяют условию «у object нет категорий, отсутствующих у device». Но нужно показывать те deviceId у которых набор категорий шире набора у objectId.

Заранее огромное спасибо за помощь. уже голову сломал.
  • Вопрос задан
  • 2840 просмотров
Пригласить эксперта
Ответы на вопрос 4
@Krechet Автор вопроса
Вот пока только это на ум пришло… при первичном тестировании вроде работает.
SELECT dc."deviceId" FROM "devices_categories" dc, "adv_objects_categories" oc WHERE dc."catId" = oc."categoryId" AND oc."objectId"=16 group by dc."deviceId" having count(dc."catId")=(select count(*) from "adv_objects_categories" WHERE "objectId"=16)
Ответ написан
youlose
@youlose
1. Не очень понятное описание задания, можно привести пример данных этих таблиц и желаемый результат?
2. «набор категорий шире» — это там где количество категорий устройства больше чем у объекта?
Ответ написан
taliban
@taliban
php программист
Вот вам псевдокод:
FROM devices_categories
LEFT JOIN object_categories on ...
GROUP BY devices_categories... HAVING count(object_categories...) = 0
Ответ написан
Комментировать
smagen
@smagen
Руководитель разработки Postgres Professional
Можно через массивы сделать:
SELECT
	"deviceId"
FROM
	devices_categories
GROUP BY
	"deviceId"
HAVING
	array_agg("catId") @> (
		SELECT
			array_agg("categoryId")
		FROM
			object_categories
		WHERE "objectId" = $1);


Кроме этого, если сделать вместо (или в дополнение к) devices_categories массив catIds в таблице device'ов, то можно будет построить по нему GIN индекс и такой запрос будет очень быстро выполняться.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы