2010-11-25 24 views
0

J'ai une table avec des colonnes comme celle-ci;La sous-requête de réécriture possède une clause dans une jointure?

site, chromosome, brin.

La paire de site et le chromosome doivent être uniques lorsqu'ils peuvent avoir plus d'un brin. Avant de charger les données, j'ai trouvé que certains des sites avaient plus d'un chromosome, ce qui est évidemment une erreur. J'essayais d'identifier les erreurs, qui sont des sites avec plus de 1 chromosome. J'y ai réfléchi et je n'ai pas pu trouver le bon SQL. J'ai donc divisé le problème. D'abord je crée une table en sélectionnant des enregistrements distincts par;

create table distinct_pair 
    as select distinct site, chromosome 
    from original_table; 

Je pourrais trouver les sites qui ont plus d'un chromosome par cette;

select site 
    from distinct_pair 
    group by site 
    having count(site)>1; 

Cela a fonctionné correctement. Ensuite, en essayant de voir toute l'information sur les erreurs de la table d'origine, j'ai fait ça;

select * from original_table 
    where site 
    in (select name from distinct_pair 
     group by site 
     having count(site)>1); 

Ensuite, cette sous-requête était beaucoup trop lente même si les colonnes étaient toutes indexées.

J'ai essayé de réécrire la requête en tant que jointure, mais cela l'a rendu difficile. S'il vous plaît aidez-moi.

===================

Merci tous ceux qui ont répondu à cette question. Mes données ressemblent à ceci.

Site | Chromosome | Strand 
N111 | 2L   | + 
N111 | 2L   | - 
N112 | 2L   | + 
N112 | 2L   | - 
N112 | 3L   | + 
N112 | 3L   | - 
.... 

Dans ce cas, N111 est correct mais N112 est une erreur car il contient deux données chromosomiques. La sous-requête de la deuxième réponse a choisi N111 ainsi que N112 à cause du brin, qui était le même problème que j'avais. Le groupe par fonction avec plusieurs colonnes a travaillé différemment de ce que j'ai deviné. Cependant, la réponse suggérée m'a donné une idée de comment fonctionne le groupe afin que je puisse le modifier légèrement pour le faire fonctionner. Les deux réponses donnent les mêmes résultats. Merci encore, les gars.

Site

Répondre

0

Vous pourriez juste trouver celui avec chromosome différent pour un site donné:

SELECT DISTINCT t1.site, t1.chromosome, t2.chromosome 
FROM original_table t1 
    INNER JOIN original_table t2 USING (site) 
WHERE t1.chromosome <> t2.chromosome
+0

Merci, ça fonctionne. Voici la version MySQL de votre réponse. (Je ne sais pas comment mettre en forme dans les commentaires, cependant). sélectionnez t1.name distinct, t1.chromosome, t2.chromosome de nature06929_s2 comme t1 interne rejoindre nature06929_s2 comme t2 en utilisant (nom) où t1.chromosome <> t2.chromosome; – microbe

+0

@microbe: Pas de mise en forme dans les commentaires. J'ai utilisé 'site' et' original_table' parce qu'ils ont été utilisés dans votre OP. – Danosaure

0

On dirait que vous voulez quelque chose comme ceci:

 SELECT site, chromosome, strand 
     FROM original_table O 
INNER JOIN (SELECT site, chromosome 
      FROM original_table 
      GROUP BY site, chromosome 
      HAVING COUNT(*) > 1) T 
     ON USING (site) 
     AND USING (chromosome) 

Le sous-requête sélectionne le site et les paires chromosomes qui se répètent plus d'une fois, alors vous joindre à la grande table. Comme il s'agit d'une INNER JOIN, elle renvoie uniquement les lignes qui ont une correspondance dans la sous-requête.

+0

Merci. Cela fonctionne aussi avec un peu de modification. J'aurais dû dire les données plus clairement. Voici la version modifiée de MySQL. sélectionner le nom, chromosome de (nom choisi, chromosome de la nature06929_s2 groupe par nom, chromosome) en tant que groupe T par son nom comptant (nom)> 1; – microbe

+0

J'ai essayé d'expliquer un peu plus mais je ne sais pas comment formater mes commentaires. désolé ... – microbe