PC SOFT

GRUPOS DE DISCUSSÃO PROFISSIONAL
WINDEVWEBDEV e WINDEV Mobile

Inicio → WINDEV 2024 → [WD9] Petit exercice SQL : voyez-vous une solution ?
[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
c'est du HF
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