多对多 SQL 查询,用于选择所有用特定单词标记的图像

jer*_*use 6 sql postgresql many-to-many

我在 Postgres 中有 2 个表:

CREATE TABLE "images" (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(300) NOT NULL,
    "relative_url" varchar(500) NOT NULL)
Run Code Online (Sandbox Code Playgroud)

CREATE TABLE "tags" (
    "id" serial NOT NULL PRIMARY KEY,
    "name" varchar(50) NOT NULL)
Run Code Online (Sandbox Code Playgroud)

为了在图像和标签之间建立多对多关系,我有另一个表:

CREATE TABLE "tags_image_relations" (
    "id" serial NOT NULL PRIMARY KEY,
    "tag_id" integer NOT NULL REFERENCES "tags" ("id") DEFERRABLE INITIALLY DEFERRED,
    "image_id" integer NOT NULL REFERENCES "images" ("id") DEFERRABLE INITIALLY DEFERRED)
Run Code Online (Sandbox Code Playgroud)

现在我必须编写一个查询,例如“选择所有带有 'apple' 和 'microsoft' 和 'google' 标记的图像的 relative_url

最优化的查询可以是什么?

jer*_*use 8

这是我写的工作查询:

SELECT i.id, i.relative_url, count(*) as number_of_tags_matched
FROM   images i
    join tags_image_relations ti on i.id = ti.image_id
    join tags t on t.id = ti.tag_id
    where t.name in ('google','microsoft','apple')
    group by i.id having count(i.id) <= 3
    order by count(i.id)
Run Code Online (Sandbox Code Playgroud)

此查询将首先显示匹配所有三个标签的图像,然后显示匹配 3 个标签中的至少 2 个,最后至少匹配 1 个标签的图像。