2

我有一个格式如下的表格:

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,其中有几对具有特定值的 (tag, val),例如:

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

或者,

(tag, val) = (C,e)

约束的数量可以改变。

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

  1. 对每个约束执行自联接
  2. 在调用程序中进行搜索(迭代)(多个 SQL 查询)
  3. (也许?)编写一个 SQL 函数来执行此操作
  4. 嵌套的 SELECT 子句(将“extID”传递到外部级别并使用WHERE extID IN (SELECT extID FROM ...)
  5. 我找不到的唯一真正的解决方案。

哪一种是首选(最快和最优雅)的方法?(当然,“当然,5. 是正确答案除外。”)

我认为多重 SELF-join 非常优雅。但是,我不知道它是否快速且相对内存效率高。

此外,我想使用一种无​​需适应即可与 MySQL、PostgreSQL 和 SQLite 一起使用的方式——这就是我不能使用 PIVOT afaiu 的原因。

4

2 回答 2

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

更新 1

由于您没有提到 and 可以重复组合,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
于 2013-02-18T08:51:34.757 回答
0

元组语法可以工作:

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

HAVING COUNT(DISTINCT tag, val) = 2确保每个约束元组至少出现一次。这意味着2需要根据查询中约束元组的数量进行调整。

如果您有两个像这样相同的行并且条件是('C', 'e')

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
于 2013-02-18T08:55:19.060 回答