Выберите несколько строк с одинаковыми значениями - PullRequest
23 голосов
/ 10 февраля 2012

У меня есть таблица, вроде как:

ID  |  Chromosome | Locus | Symbol | Dominance |
===============================================
1   |      10     |   2   |   A    |   Full    |
2   |      10     |   2   |   a    |   Rec.    |
3   |      10     |   3   |   B    |   Full    |
4   |      10     |   3   |   b    |   Rec.    |

Я бы хотел выбрать все строки с одним и тем же локусом и хромосомой. Например, строки 3 и 4. Одновременно может быть больше 2, и они могут быть не в порядке.

Я пробовал это:

SELECT *
FROM Genes
GROUP BY Locus
HAVING Locus='3' AND Chromosome='10'

Но он всегда возвращает строку 3, а не строку 4, даже если повторяется. Я думаю, что упускаю что-то очевидное и простое, но я в растерянности.

Может кто-нибудь помочь?

Ответы [ 5 ]

39 голосов
/ 10 февраля 2012

Вы должны понимать, что когда вы включаете GROUP BY в свой запрос, вы говорите SQL для объединения строк. вы получите одну строку за уникальное Locus значение. Затем Having фильтрует эти группы. Обычно вы указываете функцию aggergate в списке выбора, например:

--show how many of each Locus there is
SELECT COUNT(*),Locus FROM Genes GROUP BY Locus

--only show the groups that have more than one row in them
SELECT COUNT(*),Locus FROM Genes GROUP BY Locus HAVING COUNT(*)>1

--to just display all the rows for your condition, don't use GROUP BY or HAVING
SELECT * FROM Genes WHERE Locus = '3' AND Chromosome = '10'
9 голосов
/ 10 февраля 2012

Предполагая, что вы хотите, чтобы все строки, для которых есть другая строка с точно такими же Chromosome и Locus:

Этого можно достичь, присоединив таблицу к себе, но возвращая столбцы только с одной "стороны" объединения.

Хитрость заключается в том, чтобы установить условие соединения на "один и тот же локус и хромосома":

select left.*
from Genes left
inner join Genes right
on left.Locus = right.Locus and 
  left.Chromosome = right.Chromosome and left.ID != right.ID

Вы также можете легко расширить это, добавив фильтр в where -классе.

2 голосов
/ 10 февраля 2012

Проблема в GROUP BY - если вы группируете результаты по локусу, вы получите только один результат для локуса.

Попробуйте:

SELECT * FROM Genes WHERE Locus = '3' AND Chromosome = '10';

Если вы предпочитаете использовать синтаксис HAVING, затем GROUP BY id или что-то, что не повторяется в наборе результатов.

1 голос
/ 10 февраля 2012

Это может работать для вас:

select t1.*
from table t1
join (select t2.Chromosome, t2.Locus
    from table2
    group by t2.Chromosome, t2.Locus
    having count(*) > 1) u on u.Chromosome = t1.Chromosome and u.Locus = t1.Locus
0 голосов
/ 10 февраля 2012

Один из способов сделать это - через предложение exists:

select * from genes g
where exists
(select null from genes g1
 where g.locus = g1.locus and g.chromosome = g1.chromosome and g.id <> g1.id)

В качестве альтернативы, в MySQL вы можете получить сводку всех совпадающих идентификаторов с доступом к одной таблице, используя group_concat:

select group_concat(id) matching_ids, chromosome, locus 
from genes
group by chromosome, locus
having count(*) > 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...