2010-06-09 6 views
43

Je suis en train d'écrire la requête suivante sur postgresql:Comment faire une sous-requête Postgresql dans une clause select avec une jointure from from clause comme SQL Server?

select name, author_id, count(1), 
    (select count(1) 
    from names as n2 
    where n2.id = n1.id 
     and t2.author_id = t1.author_id 
    )    
from names as n1 
group by name, author_id 

Ce serait certainement travailler sur Microsoft SQL Server, mais elle ne présente pas du tout sur PostegreSQL. J'ai lu sa documentation un peu et il semble que je pourrais réécrire comme:

select name, author_id, count(1), total      
from names as n1, (select count(1) as total 
    from names as n2 
    where n2.id = n1.id 
     and n2.author_id = t1.author_id 
    ) as total 
group by name, author_id 

Mais qui renvoie l'erreur suivante sur PostegreSQL: « sous-requête de ne pas peut se référer à d'autres relations de même niveau d'interrogation ». Donc je suis coincé. Est-ce que quelqu'un sait comment je peux y parvenir?

Merci

+0

En fait, il semble que cela devrait fonctionner sur Postgres (peut-être 6 ans il n'y a pas :) :) – qwertzguy

Répondre

69

Je ne suis pas sûr que je comprends parfaitement votre intention, mais peut-être le suivant serait proche de ce que vous voulez:

select n1.name, n1.author_id, count_1, total_count 
    from (select id, name, author_id, count(1) as count_1 
      from names 
      group by id, name, author_id) n1 
inner join (select id, author_id, count(1) as total_count 
       from names 
       group by id, author_id) n2 
    on (n2.id = n1.id and n2.author_id = n1.author_id) 

Malheureusement, cela ajoute l'exigence de regrouper la première sous-requête par id ainsi que le nom et author_id, que je ne pense pas était voulu. Cependant, je ne suis pas sûr de savoir comment contourner cela, car vous devez avoir un identifiant disponible pour rejoindre la seconde sous-requête. Peut-être quelqu'un d'autre va trouver une meilleure solution.

Partagez et appréciez.

+0

Parfait Bob, ça a vraiment marché. Merci beaucoup! J'ai dû faire un léger changement parce que je n'ai pas besoin de la jointure avec l'id, juste le author_id. Ainsi, la requête finale est: select n1.name, n1.author_id, nombre_total_1, TOTAL_COUNT de (select id, nom, author_id, compter (1) nombre_total_1 des noms groupe par id, nom, author_id) n1 jointure (sélectionner author_id, compter (1) TOTAL_COUNT des noms groupe par author_id) sur n2 (n2.author_id = n1.author_id) maintenant que j'ai cela, ce que je veux vraiment est de diviser par nombre_total_1 TOTAL_COUNT avoir une fréquence normalisée. = D –

+0

ops, vient de réaliser que le sql n'est pas formaté correctement ici. :( Je vais donner une réponse à compléter –

+0

Je n'ai pas eu le problème Ricado parlait mais ce SQL a totalement résolu mes problèmes ...: D MERCI !!! – tftd

7

Je suis juste réponds ici avec la version formatée de la sql finale, je fonction des besoins basés sur la réponse Bob Jarvis a écrit dans mon commentaire ci-dessus:

select n1.name, n1.author_id, cast(count_1 as numeric)/total_count 
    from (select id, name, author_id, count(1) as count_1 
      from names 
      group by id, name, author_id) n1 
inner join (select author_id, count(1) as total_count 
       from names 
       group by author_id) n2 
    on (n2.author_id = n1.author_id) 
Questions connexes