Equivalent de plusieurs COUNT(x WHERE y = z) dans une requête ?

Equivalent de plusieurs COUNT(x WHERE y = z) dans une requête ? - SQL/NoSQL - Programmation

Marsh Posté le 08-02-2006 à 09:45:10    

Bonjour,
 
 
J'ai une table avec entre autres les champs suivants IDClient (Int) et statut (NVarChar)
Et je souhaiterais faire une requête de ce style-là :
 
SELECT  
     DISTINCT(IDClient),  
     COUNT(statut WHERE statut='statut1'),
     COUNT(statut WHERE statut='statut2'),
     COUNT(statut WHERE statut='statut3')  
FROM maTable  
WHERE mesConditions  
GROUP BY IDClient

 
C'est-à-dire obtenir un tableau avec 4 colonnes : 1/ IDClient, 2/ le nombre de fois où IDClient apparaît avec le statut 'statut1', 3/ le nombre de fois où IDClient apparaît avec le statut 'statut2', 4/ le nombre de fois où IDClient apparaît avec le statut 'statut3'
Ca ne me paraît pas la mort comme besoin, mais je n'arrive pas à trouver comment faire "élégamment" avec des temps d'exécution raisonnable sur une grosse table...  :(  
 
Le mieux que j'ai trouvé, c'est avec des fonctions, ce qui donnait quelque chose comme ça:
SELECT
     DISTINCT(IDClient),
     compterStatuts('statut1',IDClient,ceQuilFautPourMesConditions),
     compterStatuts('statut2',IDClient,ceQuilFautPourMesConditions),
     compterStatuts('statut3',IDClient,ceQuilFautPourMesConditions)  
FROM maTable  
WHERE mesConditions  
GROUP BY IDClient

 
Mais ça ne marche bien que quand il n'y a pas trop de champs dans ma table : dès que je passe à une grosse-grosse table, c'est beaucoup trop lent.
 
Est-ce que quelqu'un pourrait m'aider ?
 
Merci d'avance

Reply

Marsh Posté le 08-02-2006 à 09:45:10   

Reply

Marsh Posté le 08-02-2006 à 10:03:38    

Bonjour,
 
Je ne sais pas si ton SGBD accepte cette syntaxe ?
 
select distinct(IDCLIENT),
IIF(statut = 'statut1', count(statut), 0) as 'stat1',
IIF(statut = 'statut2', count(statut), 0) as 'stat2',
etc ...

Reply

Marsh Posté le 08-02-2006 à 10:54:38    

Tout d'abord, merci pour ta réponse.
 
Il s'agit d'une base SqlServer 2000, du coup j'ai traduit le IIF par un CASE, ce qui me donne ça:
SELECT  
 DISTINCT IDclient,
 (CASE
     WHEN statut ='statut1'
      THEN count(statut)
      ELSE 0
      END) AS stat1,
 (CASE
     WHEN statut = 'statut2'
      THEN count(statut)
      ELSE 0
      END) AS stat2,
 (CASE
     WHEN statut = 'statut3'
      THEN count(statut)
      ELSE 0
      END) AS stat3
FROM maTable
WHERE  pleinDeConditions
GROUP BY IDclient,statut

 
Le problème est que ça me renvoie une ligne par couple {IDclient,statut} or je n'en voudrais qu'une !
C'est-à-dire au lieu de ça:
 IDclient stat1  stat2  stat3
 99999  0  0   1
 99999  1  0   0
je voudrais ça:
 IDclient stat1  stat2  stat3
 99999  1  0   1
 
Est-ce que c'est possible ???
 
Merci d'avance
 
 

Reply

Marsh Posté le 08-02-2006 à 11:09:59    

Re,
 
Désolé, je ne connais pas SqlServer. C'était juste pour l'idée.
 
Bonne chance.

Reply

Marsh Posté le 08-02-2006 à 13:11:49    

Bon, en fait j'ai trouvé alors si ça peut intéresser quelqu'un voilà comment j'ai fait (c'est peut-être pas ce qu'il y a de mieux, mais c'est toujours beaucoup plus performant que la première solution que j'avais à base de fonctions... désolée, je débute...)
 
Le but de ma requête est de construire un tableau avec les colonnes suivantes :
IDClient,TotalDossiersOK,TotalDossiersKO,TotalDossiersEnCours
 
Je suis passée par une derived table récupérant mes IDClient,le total de dossiers OK, le total de dossiers KO, le total de dossiers EC :
SELECT  
    DISTINCT IDClient,  
     (CASE WHEN statut='OK' THEN COUNT(statut) ELSE 0 END) AS OK,  
    (CASE WHEN statut LIKE 'KO' THEN COUNT(statut) ELSE 0 END) AS KO,  
    (CASE WHEN statut = 'EC' THEN COUNT(statut) ELSE 0 END) AS EC
FROM          maTable
WHERE      mesConditions
GROUP BY IDClient, statut

 
Ce qui me renvoie une ligne par IDClient et par statut différent trouvé.
Par exemple :
IDClient    OK       KO      EC
99999       0         8         0
99999       1         0         0
 
Ensuite il suffit juste de faire des sommes...
 
SELECT  
     DISTINCT IDClient,  
     SUM(OK) AS TotalOK,  
     SUM(KO) AS TotalKO,  
     SUM(EC) AS TotalEC
FROM
       
     (SELECT  
         DISTINCT IDClient,  
         (CASE WHEN statut='OK' THEN COUNT(statut) ELSE 0 END) AS OK,  
         (CASE WHEN statut LIKE 'KO' THEN COUNT(statut) ELSE 0 END) AS KO,  
         (CASE WHEN statut = 'EC' THEN COUNT(statut) ELSE 0 END) AS EC
      FROM          maTable
      WHERE      mesConditions
      GROUP BY IDClient, statut) AS MaSousTable
GROUP BY IDClient
ORDER BY IDClient

 
Et j'obtiens  
IDClient    OK       KO      EC
99999       1         8         0
 
Merci beaucoup pc75 de m'avoir mise sur la voie...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed