Выберите несколько строк с одинаковыми значениями
У меня есть таблица, вроде этого:
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, даже если она повторяется. Я думаю, что мне не хватает чего-то очевидного и простого, но я в недоумении.
Может кто-нибудь помочь?
Ответы
Ответ 1
Вам нужно понять, что когда вы включаете 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'
Ответ 2
Предполагая, что вам нужны все строки, для которых есть еще одна строка с теми же 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
-clause.
Ответ 3
Задача GROUP BY
- если вы группируете результаты по Locus, вы получаете только один результат для каждого локуса.
Try:
SELECT * FROM Genes WHERE Locus = '3' AND Chromosome = '10';
Если вы предпочитаете использовать синтаксис HAVING
, тогда GROUP BY id
или что-то, что не повторяется в результирующем наборе.
Ответ 4
Это может сработать для вас:
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
Ответ 5
Один из способов сделать это через предложение 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