Postgres Найти все в списке кортежей - PullRequest
0 голосов
/ 21 июня 2020

Можно найти запись, которая соответствует любому кортежу из списка, например:

SELECT * FROM tags
WHERE (tags.namespace, tags.name) IN (('genre', 'Action'), ('content', 'Violence'));

Но возможно ли найти запись, которая соответствует всем кортежам из списка?

Согласно документации Postgres, это похоже на работу для = ALL:

Результат ALL - «истина», если all сравнения дают истинное значение (включая случай, когда в массиве нулевые элементы). Результатом будет «ложь», если будет обнаружен какой-либо ложный результат.

Но, как ни странно, этот оператор не кажется совместимым со списком значений кортежа. Я пробовал следующее:

SELECT * FROM tags
WHERE (tags.namespace, tags.name) = ALL (('genre', 'Action'), ('content', 'Violence'));

... что дает мне синтаксическую ошибку в первой запятой.

Я также пробовал:

SELECT * FROM tags
WHERE (tags.namespace, tags.name) = ALL (ARRAY[('genre', 'Action'), ('content', 'Violence')]);

. .. что дает мне прекрасный cannot compare dissimilar column types namespace and unknown at record column 1.

В идеале я хотел бы сохранить решение в формате списка значений.

Вот схема таблицы tags:

CREATE TYPE namespace AS ENUM ('genre', 'type', 'content', 'any');

CREATE TABLE tags (
    comic UUID NOT NULL REFERENCES comics ON DELETE CASCADE,
    namespace namespace NOT NULL,
    name VARCHAR NOT NULL,
    PRIMARY KEY(comic, namespace, name)
);

1 Ответ

1 голос
/ 21 июня 2020

Использовать агрегирование:

SELECT t.comic
FROM tags t
WHERE (t.namespace, t.name) IN (('genre', 'Action'), ('content', 'Violence'))
GROUP BY t.comic
HAVING COUNT(*) = 2;  -- 2 is the size of the list

«2» - это количество совпадающих тегов - эта версия предполагает (разумно), что теги не дублируются для данного comic.

Если вы храните значения в массиве, вы можете использовать конструкцию массива в WHERE и размер массива в HAVING.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...