Fusionner deux requêtes SELECT avec différentes clauses WHERE

9

J'ai une table de services. J'ai besoin de fusionner deux requêtes SELECT. Les deux ont des clauses where différentes. Par exemple

SELECT 
  U_REGN as 'Region', 
  COUNT(callID) as 'OpenServices',
  SUM(CASE WHEN descrption LIKE '%DFC%' THEN 1 ELSE 0 END) 'DFC'
FROM OSCL
WHERE     
  ([status] = - 3) 
GROUP BY 
  U_REGN
ORDER BY 
  'OpenServices' desc

Cela me donne un résultat

Region    | OpenServices | DFC
Karaci    | 14           | 4
Lahore    | 13           | 3
Islamabad | 10           | 4

J'ai une autre requête

SELECT 
  U_REGN as 'Region', 
  COUNT(callID) as 'ClosedYesterday'
FROM OSCL
WHERE 
  DATEDIFF(day, closeDate, GETDATE()) = 1
GROUP BY 
  U_REGN
ORDER BY 
  'ClosedYesterday' desc

Ça me donne un résultat

Region    | ClosedServices
Karachi   | 8
Lahore    | 7
Islamabad | 4

Je dois fusionner les deux résultats et afficher ClosedServices à côté de la colonne DFC.

TheSarfaraz
la source
Il y a une incohérence - votre deuxième requête produit une colonne appelée ClosedYesterday mais les données d'exemple indiquent ClosedServices.
Michael Green
Que signifie «fusionner»?
philipxy

Réponses:

15

Traitez vos deux jeux de résultats actuels comme des tableaux et joignez-les:

select
    FirstSet.Region,
    FirstSet.OpenServices,
    FirstSet.DFC,
    SecondSet.ClosedYesterday
from 
(
    SELECT U_REGN as 'Region', COUNT(callID) as 'OpenServices',
    SUM(CASE WHEN descrption LIKE '%DFC%' THEN 1 ELSE 0 END) 'DFC'
    FROM OSCL 
    WHERE ([status] = - 3) 
    GROUP BY U_REGN 
    --ORDER BY 'OpenServices' desc
) as FirstSet
inner join
(
    SELECT U_REGN as 'Region', 
    COUNT(callID) as 'ClosedYesterday'
    FROM OSCL
    WHERE DATEDIFF(day, closeDate, GETDATE()) = 1
    GROUP BY U_REGN
    --ORDER BY 'ClosedYesterday' desc
) as SecondSet
on FirstSet.Region = SecondSet.Region
order by FirstSet.Region

Pas le plus joli morceau de SQL que j'aie jamais écrit, mais j'espère que vous verrez comment cela fonctionne et comprendre comment le maintenir.

Je soupçonne qu'une requête plus performante serait une requête unique SELECTde OSCL, regroupée par U_REGN, avec chacun de vos trois compteurs en tant qu'instructions distinctes SUM(CASE ...)semblables à ce que vous faites actuellement pour DFC. Ce sera une analyse de table unique, tout au plus, en fonction de vos index et de votre schéma.

Michael Green
la source
2
Que se passe-t-il lorsqu'il y a des résultats dans une sous-requête qui ne sont pas là dans l'autre? Je soupçonne que vous voulez réellement une jointure externe complète ici.
Simon Righarts
@Simon - juste point, mais ce n'était pas le scénario donné par l'OP.
Michael Green
Merci, c'est ce que je voulais, merci! Et aussi merci @SimonRigharts. La jointure interne ne me montrait pas tous les résultats que je voulais, j'ai donc utilisé la jointure externe complète, fonctionne parfaitement :)
TheSarfaraz
6

S'appuyant sur la suggestion de Michael:

SELECT
    U_REGN AS 'Region',
    SUM(CASE WHEN [status] = -3 THEN 1 ELSE 0 END) AS 'OpenServices',
    SUM(CASE WHEN [status] = -3 AND [description] LIKE '%DFC%' THEN 1 ELSE 0 END) AS 'DFC',
    SUM(CASE WHEN DATEDIFF(day, closeDate, GETDATE()) = 1 THEN 1 ELSE 0 END) AS 'ClosedYesterday'
FROM
    OSCL
GROUP BY 
    U_REGN
ORDER BY
    'OpenServices' desc
Simon Righarts
la source
1
Merci Simon, mais j'ai utilisé la requête de @Michael Green avec jointure externe complète car cette requête me donne même les régions qui n'ont pas de service ouvert ou fermé!
TheSarfaraz