在mysql中解决intersect关键字

时间:2015-09-04 14:35:34

标签: mysql sql

我要求在mysql DB中获得某些结果的交集。但谷歌搜索后才知道没有mysql intersect关键字可用。以下是我的样本表。

gene table
+------+--------+---------+
| id   | symbol | test_id |
+------+--------+---------+
|   -1 | A      |      -1 |
|    8 | A      |       3 |
|    9 | G      |       3 |
|   -1 | A      |      -1 |
|   -2 | B      |      -1 |
|   -3 | C      |      -1 |
|    1 | A      |       1 |
|    2 | B      |       1 |
|    3 | C      |       1 |
|    4 | B      |       2 |
|    5 | C      |       2 |
|    6 | D      |       2 |
|    7 | E      |       2 |
|    8 | A      |       3 |
|    9 | G      |       3 |
|   10 | F      |       3 |
|   11 | C      |       3 |
|   12 | C      |       4 |
|   13 | G      |       4 |
|   14 | F      |       4 |
|   15 | M      |       4 |
|   16 | N      |       4 |
+------+--------+---------+

test table
+------+-------+
| id   | name  |
+------+-------+
|   -1 | test0 |
|    3 | test3 |
|   -1 | test0 |
|    1 | test1 |
|    2 | test2 |
|    3 | test3 |
|    4 | test4 |
+------+-------+

现在我想制定一个查询,它将为我提供所提供基因常见的测试。例如我将提供基因A,B,C,我应该得到以下结果:

 id    name   id    symbol 
---------------------------    
 -1 | test0 |   -1 | A
 -1 | test0 |   -2 | B
 -1 | test0 |   -3 | C
  1 | test1 |    1 | A
  1 | test1 |    2 | B
  1 | test1 |    3 | C

我只是尝试通过以下方式形成查询,但没有工作,获得空结果集,如果我使用'或'在where子句中获取where子句中所有基因的测试。

select distinct t.id, t.name, g.id, g.symbol from tests t 
join genes g on t.id = g.test_id 
where g.symbol = 'A' and g.symbol='B' and g.symbol='C';

请帮我构建查询。

2 个答案:

答案 0 :(得分:3)

诀窍是根据您的条件过滤记录,然后按test.id进行分组,以检查其是否符合所有标准:

SELECT  t.id
FROM    tests AS t
        INNER JOIN genes AS g
            ON t.id = g.test_id 
WHERE   g.symbol in ('A','B','C')
GROUP BY t.id
HAVING COUNT(DISTINCT g.symbol) = 3;

所以关键线在这里:

HAVING COUNT(DISTINCT g.symbol) = 3;

如果像测试2一样,'B'上只有匹配,那么计数将返回1并且将排除测试。您要检查的项目数必须与HAVING子句中的数字相匹配。

如果您需要获取完整数据,则只需加入表格即可:

SELECT  t.id, t.name, g.id, g.symbol
FROM    genes AS g
        INNER JOIN
        (   SELECT  t.id, t.name
            FROM    tests AS t
                    INNER JOIN genes AS g
                        ON t.id = g.test_id 
            WHERE   g.symbol in ('A','B','C')
            GROUP BY t.id, t.name
            HAVING COUNT(DISTINCT g.symbol) = 3
        ) t
            ON t.id = g.test_id;

<强> Example on SQL Fiddle

答案 1 :(得分:0)

将这些AND条件更改为OR条件,如下所示{* 1}}只能保存一个值,而不能保存多个值。这就是你得到空结果集的原因。

g.symbol

(OR)使用select t.id, t.name, g.id, g.symbol from tests t join genes g on t.id = g.test_id where (g.symbol = 'A' or g.symbol='B' or g.symbol='C') and g.test_id = 1; 运算符,如

IN