首页 > 解决方案 > 如何获取缺少 Posgtres 中标签之一的文章?

问题描述

我有一个要求,允许通过没有标签来过滤文章。

例如我有:

articles.id
A
B
tags.id
1
2
3
4
articles_tags.article_id articles_tags.tag_id
A 1
A 2
B 2
B 4

现在,我有一个标签 ID 列表,例如(3, 4). 我想要一个返回列表中缺少任何标签的文章列表的查询。在这个例子中,它会返回 A 和 B,因为它们都没有标签 3。如果我发送(1)它应该只返回B因为 A 有标签 1。

标签: sqlpostgresqljoinselect

解决方案


我会使用 PostgreSQL 数组类型来处理这个问题。

忽略articlestags表以简化:

with arraystyle as (
  select article_id, array_agg(tag_id) as tagarray
    from articles_tags
   group by article_id
)
select * from arraystyle;

 article_id | tagarray
------------+-----------
 B          | {2,4}
 A          | {1,2}
(2 rows)

拥有这种格式的 tagarray 允许您使用Array Functions 和 Operators。包含运算符之一@><@是您需要的否定形式。

with arraystyle as (
  select article_id, array_agg(tag_id) as tagarray
    from articles_tags 
   group by article_id
)
select * from arraystyle
 where not tagarray @> '{1,3}';

 article_id | tagarray 
------------+----------
 B          | {2,4}
 A          | {1,2}
(2 rows)

with arraystyle as (
  select article_id, array_agg(tag_id) as tagarray
    from articles_tags 
   group by article_id
)
select * from arraystyle
 where not tagarray @> '{1}';

 article_id | tagarray 
------------+----------
 B          | {2,4}
(1 row)

推荐阅读