SQL关键字搜索的首选方式

SQL关键字搜索的首选方式,sql,select,self-join,Sql,Select,Self Join,我有以下格式的表格: row_key extID tag val ------- ----- --- --- 1 1 A a 2 1 A b 3 1 B c 4 2 A d 5 2 C e 现在我想要所有extID,其中有几对带有特定值的标记val,例如: (tag, val) = (A,a) AND (tag, val

我有以下格式的表格:

row_key  extID  tag   val
-------  -----  ---   ---
1         1     A     a
2         1     A     b
3         1     B     c
4         2     A     d
5         2     C     e
现在我想要所有extID,其中有几对带有特定值的标记val,例如:

(tag, val) = (A,a) AND (tag, val) = (B,c)
或者

约束的数量可以更改

我可以想出几种方法来做到这一点:

对每个约束执行自连接 在调用方程序中迭代搜索多个SQL查询 大概编写一个SQL函数来实现这一点 嵌套的SELECT子句将extID传递到外部级别,并在SELECT extID FROM中使用WHERE extID。。。 唯一真正的解决办法,我就是找不到。 哪一种是最快、最优雅的方式?当然,除了5个。这是正确的答案

我认为多重自联接非常优雅。不过,我不知道它是否速度快且相对内存效率高

此外,我想使用一种与MySQL、PostgreSQL和SQLite一起工作而不进行修改的方式——这就是为什么我不能使用PIVOT afaiu

SELECT  extID
FROM    tableName
WHERE   (tag = 'A' AND val = 'a') OR
        (tag = 'B' AND val = 'c')
GROUP   BY extID
HAVING  COUNT(*) = 2
更新1

因为您没有提到tag和val可以有重复的组合,所以需要使用DISTINCT关键字

SELECT  extID
FROM    tableName
WHERE   (tag = 'A' AND val = 'a') OR
        (tag = 'B' AND val = 'c')
GROUP   BY extID
HAVING COUNT(DISTINCT tag, val) = 2

元组语法可以工作:

SELECT  extID
FROM    tableName
WHERE   (tag, val) in (('A', 'a'), ('B', 'c'))
GROUP   BY extID
HAVING  COUNT(DISTINCT tag, val) = 2
具有COUNTDISTINCT标记的val=2确保每个约束元组至少存在一次。这意味着2需要根据查询中约束元组的数量进行调整

如果您有两个相同的行,并且条件是“C”,“e”,那么这甚至可以工作:

对此的查询如下所示:

SELECT  extID
FROM    tableName
WHERE   (tag, val) in (('C', 'e'))
GROUP   BY extID
HAVING  COUNT(DISTINCT tag, val) = 1

您的示例标记val=A,A和tag,val=B,c有什么问题?@DanielHilgarth它不会返回结果,因为每一行只有一个tag值。@JW:很明显,您需要修复和。我指的是元组语法。@Dukeling这是另一个条件。@JW@Dukeling我的理解不同。我认为他在寻找一个extID值,它有A,A和B的组合,c@JW我也想过这个。问题是除了row_id之外,还有两行是相同的,当然,这会失败,因为计数会给出错误的结果…@w0lf,这就是我的答案。两种组合谢谢!COUNTDISTINCT标记val与下面版本中的键相同Hanks,我认为它与JW的答案非常相似-键是IMHO COUNTDISTINCT标记val。@user2055100:的确如此。我发布了我的答案,因为我发现元组语法更简洁,而且JW的答案在解释方面有点欠缺。
row_key  extID  tag   val
-------  -----  ---   ---
5         2     C     e
6         2     C     e
SELECT  extID
FROM    tableName
WHERE   (tag, val) in (('C', 'e'))
GROUP   BY extID
HAVING  COUNT(DISTINCT tag, val) = 1