2015-09-04 8 views
0

У меня есть требование получить пересечение некоторых результатов в DB mysql. Но после того, как googling узнал, что нет ключевого слова mysql intersect. Ниже приведены мои таблицы образцов.Работайте для ключевого слова intersect в mysql

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.

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'; 

Пожалуйста, помогите мне построить запрос.

+1

'где g.symbol в ('A',» B ',' C ') ' – splash58

+0

@ splash58 Я попробовал' или 'вместо' и 'У меня были тесты всех трех генов, но мне нужно только пересечение (общее для этих трех генов) –

+2

Зачем вам не нужно тестировать с идентификатором -1 вернулся? У этого также есть гены A, B и C? – GarethD

ответ

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

+0

Я проверю и вернусь к вам. Благодарю. –

+0

Excelent !!! .... работа совершенно. Спасибо. –

0

Измените эти AND условий на OR Условие, подобное ниже, вызывает в любой момент времени g.symbol может содержать только одно значение, а не несколько значений. поэтому вы получаете пустой набор результатов.

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; 

(OR) использовать IN оператор как

select t.id, t.name, g.id, g.symbol from tests t 
join genes g on t.id = g.test_id 
where g.symbol in ('A','B','C') 
and g.test_id = 1; 
+0

Я тоже это пробовал. Я упомянул об этом в самом вопросе. Это не сработало. Спасибо за ответ. –

+0

И да, вы получаете абсолютно правильный результат. Попробуйте проанализировать его самостоятельно, и вы это узнаете. – Rahul

+0

Я дам вам результаты запроса 1 мин. –

Смежные вопросы