|
[WD9] Petit exercice SQL : voyez-vous une solution ? |
Iniciado por michel.harrois, jun., 09 2005 12:52 AM - 8 respostas |
| |
| | | |
|
| |
Publicado em junho, 09 2005 - 12:52 AM |
Voici un petit problème SQL que je n'arrive pas à résoudre. Soit le fichier suivant, simplifié sur 3 colonnes : CodeProduit CodeNiveau âge où: - CodeProduit est une clef primaire - Code Niveau est une clef avec doublons - âge est un entier 0 à 99
Soit d'autre part 4 tranches d'âge 0-5 , 6-15, 16-30 et 31-99 Je voudrais cumuler les enregistrements du fichier par tranche d'âge. C'est à dire, obtenir le résultat suivant par une requête
CodeProduit CodeNiveau Tranche1 Tranche 2 Tranche 3 Tranche 4
Prod1 Niv1 5 0 18 7 Prod1 Niv2 0 5 250 4 Prod2 Niv1 1 8 0 17 etc...
En en mot, est-il possible de comptabiliser dans ces 4 tranches le nombre d'occurrences d'un produit + un niveau ? Je ne crois pas que ce soit possible en SQL. Mais je me trompe peut-être...
Merci,
Michel Harrois |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 11:19 AM |
Ca fonctionne en SQL, mais je ne sais pas si ça fonctionne avec HF: select codeproduit,niveau,sum(case when age between 0 and 5 then 1 else 0) as Tranche1,sum(case when age between 6 and 15 then 1 else 0) as Tranche2,sum(case when age between 16 and 30 then 1 else 0) as Tranche3,sum(case when age between 31 and 99 then 1 else 0) as Tranche4 from produit group by prod1,niv1
Frédéric. |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 11:24 AM |
Hum ca sent le case ca !
Select CodeProduit, CodeNiveau, case when isnull(age,0) between (0,5) then 1 when isnull(age,0) between (6,15) then 2 when isnull(age,0) between (16,30) then 3 when isnull(age,0) between (31,99) then 4 end AS Tranche From TaTable Order By age --Ou par le gros "case when" ca devrait revenir au meme !
Apres si tu veux comptabiliser le nombre de produits par tranche : Select count(*) From "Précédent Select a remettre ici" where Tranche="La tranche que tu veux".
Sinon si tu veux vraiment avoir un colonne par tranche :
Select CodeProduit, CodeNiveau, case when isnull(age,0) between (0,5) then 1 else 0 end AS Tranche1, case when isnull(age,0) between (6,15) then 1 else 0 end AS Tranche2, case when isnull(age,0) between (16,30) then 1 else 0 end AS Tranche3, case when isnull(age,0) between (31,99) then 1 else 0 end AS Tranche4 From TaTable
Ensuite tu manipules cette "table" comme tu veux -> Pour avoir la somme par tranche Select CodeProduit,CodeNiveau, sum(case when isnull(age,0) between (0,5) then 1 else 0 end ) as tranche1, sum(...).., .. From TaTable Group By CodeProduit,CodeNiveau
Alors je n ai pas verifie la syntaxe ( le between !!!!), mais en gros c ca le principe ! (a verifier ce qu on peut faire avec la somme .... Si ca ne marche pas fait un select sum.... du select qui donne la table avec les tranches, heu tu suis la??).
Voila bon dev, Damien |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 12:21 PM |
avec quelle base de données ?
Dam |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 12:52 PM |
C'est effectivement possible.
Voici le code pour le faire si la table hébergée sous SQL Server
SELECT CodeProduit, CodeNiveau, SUM(CASE WHEN Age<=5 THEN 1 ELSE 0 END) as Tranche0005, SUM(CASE WHEN Age>5 and Age< THEN 1 ELSE 0 END) as Tranche0615, SUM(CASE WHEN Age>15 and Age<0 THEN 1 ELSE 0 END) as Tranche1630, SUM(CASE WHEN Age>30 and Age<™ THEN 1 ELSE 0 END) as Tranche3199 FROM TblAge GROUP BY CodeProduit, CodeNiveau
Mais si la table est un fichier hyperfile, l'instruction CASE ne fonctionne pas. Il faut donc utiliser la requête SQL suivante:
SELECT TblAge.CodeProduit AS CodeProduit, TblAge.CodeNiveau AS CodeNiveau, SUM(SIGN(SIGN(TblAge.Age - 0) - SIGN(TblAge.Age - 5))) AS Tranche0005, SUM(SIGN(SIGN(TblAge.Age - 6) - SIGN(TblAge.Age - 15))) AS Tranche0615, SUM(SIGN(SIGN(TblAge.Age - 16) - SIGN(TblAge.Age - 30))) AS Tranche1630, SUM(SIGN(SIGN(TblAge.Age - 31) - SIGN(TblAge.Age - 99))) AS Tranche3199 FROM TblAge GROUP BY CodeProduit, CodeNiveau
Explication : La fonction SIGN renvoie 1, 0 ou -1 selon que le nombre donné est positif, nul ou négatif. Donc SIGN(TblAge.Age - BorneInf) - SIGN(TblAge.Age - BorneSup) renvoi un nombre positif si l'Age est dans la plage (le 1er SIGN vaux 0 ou 1, le 2ème 0 ou -1. les 2 ne pouvant pas valoir 0 en même temps), 0 sinon (les 2 SIGN sont soit = 1, soit =-1) On réapplique SIGN pour être sur d'avoir un chiffre unitaire ou 0 On peut alors faire la somme des ces chiffres |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 4:03 PM |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 09 2005 - 4:14 PM |
J'ai un peu trop simplifié... En fait age est une chaine de la forme AAAAMMJJ où par exemple, un enfant de 3ans et 1/2 donnerait '00030600' |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 10 2005 - 10:55 AM |
N'ayant pas de fonction de conversion chaine->nombre utilisable dans les SQL sur HF, je crois malheureusement qu'il n'est pas possible de créer la requête que vous demandez.
Je vous conseille donc de convertir cette chaine en nombre. Vous pourrez alors utiliser la requête que j'ai donnée plus haut, à savoir :
SELECT TblAge.CodeProduit AS CodeProduit, TblAge.CodeNiveau AS CodeNiveau, SUM(SIGN(SIGN(TblAge.Age - 0) - SIGN(TblAge.Age - 5))) AS Tranche0005, SUM(SIGN(SIGN(TblAge.Age - 6) - SIGN(TblAge.Age - 15))) AS Tranche0615, SUM(SIGN(SIGN(TblAge.Age - 16) - SIGN(TblAge.Age - 30))) AS Tranche1630, SUM(SIGN(SIGN(TblAge.Age - 31) - SIGN(TblAge.Age - 99))) AS Tranche3199 FROM TblAge GROUP BY CodeProduit, CodeNiveau
Michaël |
| |
| |
| | | |
|
| | |
| |
Publicado em junho, 10 2005 - 1:44 PM |
C'est un peu étrange comme maniere de faire non ?
n'est-il pas plus judicieux de stocker la date de naissance qui elle ne change pas tous les jours ?
Dam |
| |
| |
| | | |
|
| | | | |
| | |
|