2009-01-14 19 views
1

Je fais un calcul de probabilité. J'ai une requête pour calculer le nombre total de fois qu'un événement se produit. À partir de ces événements, je souhaite connaître le nombre de fois qu'un sous-événement se produit. La requête pour obtenir le total des événements est de 25 lignes et je ne veux pas simplement copier + coller deux fois.SQL - Utiliser les résultats d'une requête comme base pour deux autres requêtes dans une instruction

Je veux faire deux choses à cette requête: calculer le nombre de lignes en elle, et calculer le nombre de lignes dans le résultat d'une requête sur cette requête. À l'heure actuelle, la seule façon de le faire est de remplacer (@ total @ par la requête compliquée pour obtenir toutes les lignes, et @ conditions @ par les conditions moins compliquées que les lignes, de @ total @, doivent avoir pour correspondre le sous-événement):

SELECT (SELECT COUNT(*) FROM (@[email protected]) AS t1 WHERE @[email protected]) AS suboccurs, 
     COUNT(*) AS totaloccurs FROM (@[email protected]) as t2 

Comme vous le constatez, @ total @ est répété deux fois. Y at-il un moyen de contourner cela? Y a-t-il une meilleure façon de faire ce que j'essaie de faire? Pour souligner à nouveau: @ conditions @ dépend de ce que @ total @ renvoie (il fait des choses comme t1.foo = bar).

Quelques notes finales: @ total @ par lui-même prend ~ 250ms. Cette requête plus compliquée prend ~ 300ms, donc postgres fait probablement une certaine optimisation, elle-même. Pourtant, la requête semble terriblement laide avec @ total @ littéralement collé deux fois.

Répondre

1
SELECT COUNT(*) as totaloccurs, COUNT(@[email protected]) as suboccurs 
FROM (@[email protected] as t1) 
+0

génial! Cela fonctionne en fait environ 10-20ms plus lentement, drôlement ... mais j'étais plus préoccupé par la façon dont le code avait l'air, aussi, juste un montage mineur que j'ai dû faire. – Claudiu

0

Mettre la sous-requête réutilisée dans une table temporaire, puis sélectionnez ce que vous avez besoin de la table temporaire.

6

Si votre sql prend en charge l'affacturage de sous-requête, il est alors possible de le réécrire à l'aide de l'instruction WITH. Cela permet aux sous-requêtes d'être utilisées plus d'une fois. Avec va les créer comme une vue en ligne ou une table temporaire dans Oracle.

Voici un exemple inventé.

WITH 
x AS 
(
    SELECT this 
    FROM THERE 
    WHERE something is true 
), 
y AS 
(
    SELECT this-other-thing 
    FROM somewhereelse 
    WHERE something else is true 
), 
z AS 
(
    select count(*) k 
    FROM X 
) 
SELECT z.k, y.*, x.* 
FROM x,y, z 
WHERE X.abc = Y.abc 
0

@EvilTeach:

Je ne l'ai pas vu le « avec » (probablement pas mis en œuvre dans :-(Sybase) Je l'aime. Est-ce que vous avez besoin en un seul morceau ENSUITE loin, avec encore moins cruel que les tables temporaires Cool