2010-10-26 5 views
2

J'ai deux requêtes similaires sur la même table et la même où condition mais différentes sélections sur elle.combinant deux requêtes sql en un?

Select flatpos from archdetails 
where version='1.3' AND compname IN (
    select distinct compname from svn3 where revno='r270294' 
) 

ET

select count(distinct compname), 
    sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END), 
    min(flatLoopIndex) 
from archdetails 
where version='1.3' 
AND compname IN (
    select distinct compname from svn3 where revno='r270294' 
) 

Comme vous pouvez voir la requête est sur la même table archdetails et où est la condition même pour les deux aussi bien.

requête 1 va afficher quelque chose comme

12
47

requête 2 va afficher quelque chose comme

396 43 1

Je voudrais que la sortie soit

12 396 43 1
47 396 43 1

Je ne peux évidemment pas les combiner par un groupe par.

Chacune de ces requêtes s'exécute en x fois. Je sais que je peux simplement placer ces requêtes dans la clause from d'une nouvelle requête et obtenir le résultat souhaité, mais la nouvelle requête s'exécute en deux fois.

Y a-t-il un moyen plus rapide puisque la base de données doit essentiellement être analysée une seule fois et que c'est juste une question de formatage.

Merci

+0

Merci, je ne m'en suis pas rendu compte. Je le ferais immédiatement. – Gaurav

+0

Le formatage n'est pas le travail de votre SGBDR. Ces lignes n'ont rien en commun. Sauf si vous faites un CROSS JOIN (mettre la deuxième requête dans la clause FROM de la première pour MySQL), je ne vois pas comment vous pouvez faire cela. –

+0

Ce n'est pas évident pour moi, pourquoi ne pouvez-vous pas les combiner par un groupe de. –

Répondre

0

Sélectionnez les résultats de la première requête dans une table temporaire. Ensuite, pour obtenir le premier jeu de résultats, select * à partir de cette table temporaire.

Pour obtenir le second jeu de résultats, joignez la table temporaire à la deuxième requête sans ajouter d'autres clauses clause et aucune colonne sélectionnée dans la table temporaire.

(Si l'optimiseur réussit à exécuter la deuxième requête N fois, stash les résultats de la deuxième requête en deuxième table temporaire et se joindre à 2 tables temporaires)

create temporary table tmp1 
Select flatpos from archdetails 
where version='1.3' AND compname IN (
    select distinct compname from svn3 where revno='r270294' 
) 

create temporary table tmp2 
select count(distinct compname) as c, 
    sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) as s, 
    min(flatLoopIndex) as m 
from archdetails 
where version='1.3' 
AND compname IN (
    select distinct compname from svn3 where revno='r270294' 
) 

select * from tmp1 

select tmp2.c, tmp2.s, tmp2.m from tmp1, tmp2 
+0

Je pense que ma solution originale serait beaucoup plus rapide 'sélectionnez t1.flatpos, t2.a, t2.b, t2.c de (sélectionnez flatpos de archdetails où version = '1.3' AND compname IN (sélectionner un nom de fichier distinct de svn3 où revno = 'r270294')) en tant que t1, (sélectionner count (nom de composant distinct) en tant que, sum (CASE WHEN inFlat = 1 THEN 1 ELSE 0 END) en tant que b, min (flatLoopIndex) c à partir de archdetails où version = '1.3' AND compname IN (sélectionner un nom de fichier distinct de svn3 où revno = 'r270294')) comme t2'; – Gaurav

+0

Pas sûr que ce soit le cas mais pour être honnête trop pressé pour le temps de tester - n'hésitez pas à le profiler pour le savoir :) Assurez-vous simplement de tester sur des ensembles de données volumineux – DVK

0

MISE À JOUR:

Vous pourrait être en mesure de gagner un peu en enlevant un des 'select distinct compname from svn3 where revno='r270294''

par

SELECT ad.flatpos , 
    totals.compname, 
    totals.inFlat, 
    totals.flatlooopindex 

FROM 
    archdetails ad 
    INNER JOIN 
    (select count(distinct compname) compname, 
     sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) inFlat, 
     min(flatLoopIndex) flatlooopindex 
    from archdetails 
    where version='1.3' 
    AND compname IN (
      select distinct compname from svn3 where revno='r270294' 
    )) totals 
    ON ad.compname = totals.compname 
+0

ouais c'est exactement ce que j'ai mentionné dans ma question. Cela prend cependant 2x fois. Donc pas d'amélioration. Merci cependant – Gaurav

+0

Manqué ce dernier paragraphe. J'ai mis à jour la réponse pour donner une alternative –

+0

Je ne sais pas pourquoi mais cela retourne un résultat vide. Je pense que je vais m'en tenir à la solution originale. – Gaurav