postgresql - 使用 IN 子句连接表,其中必须匹配所有值
问题描述
我在这里看到了一些类似的答案,但我无法让它们工作。我基本上有两张表,一张有内容,一张桥接标签。我想获取具有关联标签的内容。如果我提供超过 1 个标签,我只想要包含所有标签的内容,而不仅仅是任何标签
我的第一次尝试是做SELECT DISTINCT contentid FROM content INNER JOIN tags WHERE tagid IN (tagList)
. 显然,这会导致内容具有 ANY 传入的标记值,而不是所有传入的标记值。
阅读后我尝试做一个不存在,但奇怪的是它没有按照我认为的那样工作。我的查询现在是:
SELECT DISTINCT contentid
FROM content
WHERE contentid NOT IN (
SELECT contentid
FROM content
LEFT JOIN tags ON tags.contentid = content.contentid AND tags.tagid IN (tagList)
WHERE tags.tagid IS NULL
)
编辑(在测试以下内容时,我删除了WHERE tags.tagid IS NULL
以查看结果,但即使使用它,我也没有得到预期的结果)
如果我运行子查询并在 tagList 中传递特定 contentid 中缺少的单个值,我会在 tagid 中得到一个 NULL 值。因此,它将按预期从父查询中删除。如果我在为特定 contentid 存在的 tagList 中传入单个值,则它不在子查询中,因此存在于父查询中。
如果我传入多个值(一个现有值,一个特定 contentid 缺失),我只会从子查询中获得 1 行,它不是 NULL 行,因此它不会按预期过滤掉它。
我在这里想念什么?而如何做到这一点呢?
解决方案
如果我对您的理解正确:“一个内容有很多标签”......那么,给定一个 N 个标签的列表,您希望内容具有(至少)与它们相关联的那些 N 个标签,对吧?
我认为您可以使用这样的STRING_AGG()函数解决此问题...
SELECT
c.id,
STRING_AGG(t.value, ', ' ORDER BY t.value) AS "TAG_LIST"
FROM
content c
INNER JOIN tag t ON c.id = t.content_id
WHERE
t.value IN (<tagList>)
GROUP BY
c.id
HAVING
STRING_AGG(t.value, ', ' ORDER BY t.value) = <tagList as CSV in ORDER!>
;
例子:
-- Return those tagged as first message:
SELECT
c.id,
STRING_AGG(t.value, ', ' ORDER BY t.value) AS "TAG_LIST"
FROM
content c
INNER JOIN tag t ON c.id = t.content_id
WHERE
t.value IN ('message', 'first')
GROUP BY
c.id
HAVING
STRING_AGG(t.value, ', ' ORDER BY t.value) = 'first, message'
;
我设法准备了一个小小提琴来测试这个概念(不知道那些小提琴能持续多久)
推荐阅读
- memory - 为什么使用 unsafe Rust 访问超出范围的变量时没有段错误?
- javascript - 如何正确编码用于 Chart.js 的 Javascript/Ajax
- python - 带有重叠按钮的 Tkinter 背景?
- c# - 附加到进程 IIS 未命中断点
- c# - Box Api GET 具有偏移和限制的文件夹项目不起作用
- python - Statsmodels:从 VARMAX.fit() 获取误差相关矩阵
- angular - 如何为每个随机路由提供一个 Angular 应用程序实例(例如在 meet.jit.si 中)
- caching - C: 如何防止使用 mmap 崩溃时的数据丢失?
- android - Android Azure Active Directory 身份验证库 (ADAL) - ActivityThread:handleWindowVisibility:令牌 android.os.BinderProxy@ 没有活动
- asp.net-core - Blazor:实现 404 未找到页面