web-dev-qa-db-fra.com

Sélectionnez plusieurs lignes avec la même valeur (s)

J'ai une table, un peu comme ça:

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.    |

Je voudrais sélectionner toutes les lignes avec le même locus et le même chromosome. Par exemple, lignes 3 et 4. Il peut y avoir plus de 2 à la fois et ils peuvent ne pas être en ordre.

J'ai essayé ceci: 

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

Mais elle renvoie toujours la ligne 3, jamais la ligne 4, même si elle est répétée. Je pense que je manque quelque chose d’évident et de simple, mais je suis perdu. 

Quelqu'un peut aider?

22
user1202673

Vous devez comprendre que lorsque vous incluez GROUP BY dans votre requête, vous indiquez à SQL de combiner des lignes. vous obtiendrez une ligne par valeur Locus unique. La Having filtre ensuite ces groupes. Habituellement, vous spécifiez une fonction aggergate dans la liste de sélection comme:

--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'
38
KM.

En supposant que vous vouliez toutes les lignes pour lesquelles il existe une autre ligne avec exactement les mêmes Chromosome et Locus:

Vous pouvez y parvenir en joignant la table à elle-même, mais en ne renvoyant que les colonnes d'un "côté" de la jointure.

L'astuce consiste à définir la condition de jointure sur "le même locus et le même chromosome":

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

Vous pouvez également facilement l'étendre en ajoutant un filtre dans une clause where-.

8
Matt Fenwick

Le problème est GROUP BY - si vous regroupez les résultats par locus, vous n’obtenez qu’un résultat par locus.

Essayer:

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

Si vous préférez utiliser la syntaxe HAVING, alors GROUP BY id ou quelque chose qui ne se répète pas dans le jeu de résultats.

2
JYelton

Cela peut fonctionner pour vous:

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
1
dasblinkenlight

Une façon de procéder consiste à utiliser une clause 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)

Sinon, vous pouvez obtenir dans MySQL un résumé de tous les identifiants correspondants avec un seul accès à une table, en utilisant group_concat:

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