2011-09-02 3 views
5

J'ai cherché beaucoup de sujets et n'ai pas trouvé la réponse, ou la question était trop complexe. Alors ok. C'est ma première question. Voici le SQLSqlAlchemy fermeture dans la sous-requête

SELECT parent.*, 
(
    SELECT COUNT(*) 
    FROM child 
    WHERE parent.id = child.parent_id 
) 
FROM parent 

Comment faire cette clause sqlalchemy?

WHERE ui.invited_by = u.id 

Peut-il être reproduit dans les collections? expressions sql? P.S. Je sais que cela peut être fait par group_by. Mais j'ai besoin de sous-requête.

Merci.

+0

Pourquoi avez-vous besoin d'une sous-requête? – SingleNegationElimination

+1

C'est une bonne question. J'ai besoin d'agrégations dans toutes les tables (2 millions de lignes). Si j'essaie de 'grouper', mon mysql commence à construire une table temporaire. il peut faire cela des heures avant que je puisse commencer à recevoir des lignes. De même, vous ne pouvez pas filtrer normalement les requêtes de regroupement si vous voulez des vracs. Donc, je reçois juste ID et deux sélectionne avec agrégation. Et cela ne dure que 5 minutes si je récupère des lignes via des curseurs côté serveur. – enomad

Répondre

1

Je trouve ici une réponse vraiment géniale. Mais aussi trop compliqué. Tout d'abord je veux dire que la fermeture dans le monde de sql est CORRÉLATION.

Ce n'est pas la même chose mais ça m'aide.

pparent = Parent.__table__.alias('pparent') # using table directly to alias. 

subquery = s.query(count(Child.id)).join(pparent) # usual thing but use aliased table. 

s.query(Parent, subquery.filter(Parent.id == pparent.id).correlate(Parent).as_scalar()) #magic 
1

La requête SA (sous-requête à l'aide) vous donnera les résultats que vous voulez:

sq = session.query(Child.parent_id, func.count(Child.id).label("child_num")).group_by(Child.parent_id) 
sq = sq.subquery() 
# use outerjoin to have also those Parents with 0 (zero) children 
q = session.query(Parent, sq.c.child_num).outerjoin(sq) 
q = q.filter(Parent.id == 1) # add your filter here: ui.invited_by = u.id 
for x in q.all(): 
    print x 

bien que la sous-requête est pas exactement comme vous l'avez décrit, mais plutôt quelque chose comme:

SELECT  parent.*, 
      anon_1.child_num AS anon_1_child_num 
FROM  parent 
LEFT JOIN (SELECT child.parent_id AS parent_id, 
        count(child.id) AS child_num 
      FROM child 
      GROUP BY child.parent_id 
      ) AS anon_1 
     ON parent.id = anon_1.parent_id 

toujours pas Je ne comprends pas pourquoi vous avez besoin d'une sous-requête comme vous l'avez décrit.