SELECT ... WHERE t1.tag = 'bob' AND t2.tag = 'foo' AND t1.idx = t2.idx 在同一个 table

SELECT ... WHERE t1.tag = 'bob' AND t2.tag = 'foo' AND t1.idx = t2.idx on same table

我有一个带有数据

的 postgres table (idx int, tag varchar)
1 T1
1 T2
1 T4
2 T2
2 T3
2 T4
3 T1
3 T4
....

如果 T1 和 T2 都匹配,我想查询 return 结果。 但是我想要一个可变数量的 T 来匹配。

我可以根据参数的数量在 运行 时创建 SQL,但我可以仅使用 SQL 来创建吗?

我试过了

SELECT t1.idx, t1.tag, t2.tag, t3.tag from tags t1, tags t2, tags t3 WHERE  t1.idx = t2.idx AND t1.tag = 'T1' AND t2.tag = 'T2' AND t1.idx = t3.idx AND t3.tag = 'T3';

这行得通。但是,如果我有 2 或 5 个不同的 T 怎么办?我这样做 5 次吗?

想要一个 return 匹配搜索的所有 idx 的列表。

这是您要找的吗? (这是在 mysql 中完成的,但你问的是标准 SQL 问题)。

select t.idx, t.name
from test t INNER JOIN test t2
         on t.name = t2.name

您可以使用聚合来做到这一点:

select idx
from tags
where tag in ('T1', 'T2')
group by idx
having count(distinct tag) = 2;

请注意,以上内容也会 return 具有附加标签的值。所以上面的 returns 那些,至少有这两个标签。

如果您需要五个标签,请扩展 IN 列表并调整 count() 的条件以匹配 IN 列表中的元素数。

tags (tag, idx) 上的索引会加快速度。

a_horse_with_no_name 回答了 SQL 问题,谢谢。 JavaScript代码是

 const seltag = "SELECT idx FROM tags WHERE tag = ANY() GROUP BY idx having count(distinct tag) = "
 let tags = JSON.parse(args[0]).split(',').map((itm) => itm.trim())
 pool.query(seltag, [tags, tags.length])