选择具有相同值的多个行

时间:2012-02-10 18:40:54

标签: sql rows

我有一张桌子,有点像这样:

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 个答案:

答案 0 :(得分:39)

您需要了解在查询中包含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'

答案 1 :(得分:8)

假设您希望所有行与另一行具有完全相同的ChromosomeLocus

您可以通过将表连接到自身来实现此目的,但只能从一个"侧返回列#34;加入。

诀窍是将连接条件设置为"相同的基因座和染色体":

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 :(得分:2)

问题是GROUP BY - 如果您按基因座对结果进行分组,则每个基因座只能获得一个结果。

尝试:

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

如果您更喜欢使用HAVING语法,那么GROUP BY id或结果集中不重复的内容。

答案 3 :(得分:1)

这可能对您有用:

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

答案 4 :(得分:0)

这样做的一种方法是通过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获取具有单个表访问权限的所有匹配ID的摘要:

select group_concat(id) matching_ids, chromosome, locus 
from genes
group by chromosome, locus
having count(*) > 1