Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/06/2011, 17h56   #1
Nouveau Membre du Club
 
Inscription : juin 2009
Messages : 121
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 121
Points : 36
Points : 36
Par défaut Moyenne d'une colonne par rapport à une catégorie

Bonjour ,
Alors voila j'essaye de calculer la valeur moyenne d'une catégorie pour chaque mois et j'arrive pas du tous a trouver la requête donc j'ai essayé ceci

Code :
1
2
3
4
SELECT rapport_position.date_rapport, rapport_position.position_moteur, rapport_position.id_kw ,kw_adgroup.id_adgroup 
FROM rapport_position 
JOIN kw_adgroup ON kw_adgroup.id_kw = rapport_position.id_kw 
WHERE rapport_position.id_prestation = '2'
qui me retourne
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
date_rapport   position_moteur  id_kw  id_adgroup  
2011-01-28 		76 	2 		1 
2011-01-28 		88 	81 		1 
2011-01-28 	        100 	310             2 
2011-01-28 		100 	309	 	2 
2011-01-28 		45 	3 		1 
 
2011-02-15 		53 	310 	        2 
2011-02-22 		1337    3 		1 
2011-02-28 		23        2 		1 
2011-02-28 		75      81 		1 
2011-02-28 		88    310 	        2 
2011-02-28 		75    309 	        2 
2011-02-28 		29       3 		1
J'ai essayer de placer un
Code :
AVG (rapport_position.position_moteur) AS moyenne
et un mais ça ne donne pas le résultat attendu
misakilou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/06/2011, 18h19   #2
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
Toutes les colonnes qui ne font pas l'objet d'une fonction de regroupement doivent être reprises dans la clause GROUP BY.

Dans ton cas, cela donnerait :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
SELECT  rapport_position.date_rapport
    ,   AVG(rapport_position.position_moteur)
    ,   kw_adgroup.id_kw
    ,   kw_adgroup.id_adgroup 
FROM    rapport_position 
    INNER JOIN
        kw_adgroup 
        ON  kw_adgroup.id_kw = rapport_position.id_kw 
WHERE   rapport_position.id_prestation = '2'
GROUP BY rapport_position.date_rapport
    ,   kw_adgroup.id_kw
    ,   kw_adgroup.id_adgroup
Mais est-ce bien ce que tu recherches ?
__________________
Modérateur Langage SQL
Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
N'oubliez pas le bouton et pensez aux balises [code]
Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/06/2011, 18h21   #3
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

Quel est votre SGBDR ?

vous pouvez essayer ceci :
Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
 
SELECT 
    YEAR(rapport_position.date_rapport) AS annee,     
    MONTH(rapport_position.date_rapport) AS Mois,
    AVG(rapport_position.position_moteur) AS MoyennePosition
FROM rapport_position 
JOIN kw_adgroup 
    ON kw_adgroup.id_kw = rapport_position.id_kw 
WHERE rapport_position.id_prestation = '2'
GROUP BY 
    YEAR(rapport_position.date_rapport) ,     
    MONTH(rapport_position.date_rapport)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 09h16   #4
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Salut !

Citation:
Envoyé par al1_24 Voir le message
Toutes les colonnes qui ne font pas l'objet d'une fonction de regroupement doivent être reprises dans la clause GROUP BY.
...
Mais est-ce bien ce que tu recherches ?
Rigolo ta formule magique que tu ressors à chaque fois.
Mais ce n'est pas vrai, ou du moins la formulation induit en erreur (comme le montre la solution que tu proposes au pif ensuite).

=> doivent être reprises dans la clause GROUP BY... ou sorties du SELECT... ou se voir appliquer un fonction de regroupement... ou ou ou. Pas de formule magique cela dit, dommage.

En fait, tu peux de manière safe intégrer les colonnes dans le GROUP BY uniquement lorsque cela ne change pas la granularité des groupes, ce qui arrive en gros pour toutes les colonnes qui "dépendent" de la clef de regroupement. Genre quand la clef primaire d'une des tables de la requête est dans le GROUP BY, tu peux y ajouter de manière safe toutes les colonnes de cette table.
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 10h45   #5
Nouveau Membre du Club
 
Inscription : juin 2009
Messages : 121
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 121
Points : 36
Points : 36
Je me suis peut être mal expliqué :/ enfin voila le résultat que j essaye d'avoir
Code :
1
2
3
4
5
6
	  date_rapport	id_adgroup	AVG
	  2011-01-28	1			69.6666  ((76 + 88 + 45)/3 = 69.6666))
	  2011-01-28	2			100	((100+100)/2 = 100)
 
	  2011-02-28	1			366 (((1337 + 23 + 75 + 29)/4 = 366))
	  2011-02-28	2			72 ((53 + 88 + 75) /3  = 72))
Après je sais si c'est possible de faire ceci en une seule requête
( Je suis en Mysql )
misakilou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 10h59   #6
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
cela devrait fonctionner :
Code sql :
1
2
3
4
5
6
7
8
 
SELECT Rapport_position.Date_rapport,
       Kw_adgroup.Id_adgroup,
       AVG(Rapport_position.Position_moteur)
  FROM Rapport_position
    INNER JOIN Kw_adgroup ON Kw_adgroup.Id_kw = Rapport_position.Id_kw
WHERE Rapport_position.Id_prestation = '2'
GROUP BY Rapport_position.Date_rapport, Kw_adgroup.Id_adgroup
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 11h21   #7
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
Non, il faut prendre la requête d'aieuuu et ajouter Id_adgroup dans le GROUP BY et dans le select.

(Car la ligne du 25-02 est regroupée avec les lignes du 28-02)
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 11h25   #8
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
il est également possible d'ajouter MAX(date_rapport) pour avoir la date du dernier rapport (avec le jours) en plus (ou à la place ) de l'année et du mois...
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 11h31   #9
Membre émérite
 
Homme Olivier Dehorter
Ingenieur de recherche - Ecologue
Inscription : juin 2003
Messages : 697
Détails du profil
Informations personnelles :
Nom : Homme Olivier Dehorter
Localisation : France

Informations professionnelles :
Activité : Ingenieur de recherche - Ecologue

Informations forums :
Inscription : juin 2003
Messages : 697
Points : 837
Points : 837
Citation:
Envoyé par pacmann Voir le message
Non, il faut prendre la requête d'aieuuu et ajouter Id_adgroup dans le GROUP BY et dans le select.

(Car la ligne du 25-02 est regroupée avec les lignes du 28-02)
je me référais au message précédent, alors qu'il était bien précisé dans le premier message qu'il fallait une info par mois
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 11h31   #10
Nouveau Membre du Club
 
Inscription : juin 2009
Messages : 121
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 121
Points : 36
Points : 36
Merci beaucoup

Code :
1
2
3
4
5
6
SELECT rapport_position.date_rapport, kw_adgroup.id_adgroup, AVG( rapport_position.position_moteur ) AS MoyennePosition
FROM rapport_position
JOIN kw_adgroup ON kw_adgroup.id_kw = rapport_position.id_kw
WHERE rapport_position.id_prestation = '2'
GROUP BY YEAR( rapport_position.date_rapport ) , MONTH( rapport_position.date_rapport ) , kw_adgroup.id_adgroup
LIMIT 0 , 30
Citation:
il est également possible d'ajouter MAX(date_rapport) pour avoir la date du dernier rapport (avec le jours) en plus (ou à la place ) de l'année et du mois...
Je crois qu'il me le fait automatiquement voila ce qu'il me sort
Code :
1
2
3
4
5
date_rapport  id_adgroup  MoyennePosition  
2011-01-28     1            69.6667 
2011-01-28     2            100.0000 
2011-02-28     1            366.0000 
2011-02-28     2            72.0000
misakilou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/06/2011, 12h21   #11
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
oui, mais vous êtes sous MySQL, et si un jour ça lui chante de sortir 2011-02-15 à la place de 2011-02-28, il ne privera pas, et ne vous demandera pas votre avis

Cette syntaxe n'est pas normalisée (voir la remarque de al1_24) et des dires même de la doc de MySQL, il ne faut pas le faire, et les résultats ne sont pas garanti.

Bref, sur plusieurs dates, vous en voulez une, à vous de définir la règle de sélection en fonction de vos besoins : la date la plus ancienne (min), la plus récente (max)...
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/06/2011, 10h56   #12
Nouveau Membre du Club
 
Inscription : juin 2009
Messages : 121
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 121
Points : 36
Points : 36
Bonjour ,
Je ré-ouvre ce message , j'ai un autre petit problème , j'essaye de faire le contraire c 'est a dire calculer la valeur moyenne sur la date le plus ancienne dans mon cas (2011-01-28)

Code :
1
2
3
4
5
6
SELECT MIN(rapport_position.date_rapport) AS min_date, adgroup.adgroup, AVG( rapport_position.position_moteur ) AS MoyennePosition , couleur.couleur_hexa
			FROM rapport_position
			JOIN kw_adgroup ON kw_adgroup.id_kw = rapport_position.id_kw
			JOIN adgroup ON adgroup.id_adgroup = kw_adgroup.id_adgroup
			JOIN couleur ON adgroup.id_couleur = couleur.id_couleur
			WHERE rapport_position.id_prestation = "2" GROUP BY kw_adgroup.id_adgroup
sauf qu'au lieu de me ressortir
Code :
1
2
3
date_rapport  id_adgroup  MoyennePosition  
2011-01-28     1            69.6667 
2011-01-28     2            100.0000
il me sort
Code :
1
2
3
4
 
min_date  adgroup  MoyennePosition 
2011-01-28 Generiques 43.7895 
2011-01-28 Destinations 57.6154
J'ai l'impression qu'il me calcule pas la valeur moyenne par rapport a catégorie
misakilou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/06/2011, 11h03   #13
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

Vous prenez le MIN de la date, mais vous faites les moyenne sur toutes les données. Vous devez ajouter un filtre sur la date, pour ne faire la moyenne que sur les valeurs correspondant aux dates qui vous intéressent....

mais...

Si vous n'avez qu'une seule ligne par date et par groupe, heu, une moyenne sur une seule valeur, c'est la valeur elle-même
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/06/2011, 11h21   #14
Nouveau Membre du Club
 
Inscription : juin 2009
Messages : 121
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 121
Points : 36
Points : 36
oki...

Code :
1
2
3
4
5
6
7
8
SELECT MIN( rapport_position.date_rapport ) AS min_date, adgroup.adgroup, AVG( rapport_position.position_moteur ) AS MoyennePosition, couleur.couleur_hexa
FROM rapport_position
JOIN kw_adgroup ON kw_adgroup.id_kw = rapport_position.id_kw
JOIN adgroup ON adgroup.id_adgroup = kw_adgroup.id_adgroup
JOIN couleur ON adgroup.id_couleur = couleur.id_couleur
WHERE rapport_position.id_prestation = "2"
AND rapport_position.date_rapport = "2011-01-28"
GROUP BY adgroup.adgroup, DAY( rapport_position.position_moteur ) , MONTH( rapport_position.position_moteur ) , YEAR( rapport_position.position_moteur )
Je suis obligé de mettre en dur la date ??? parce que sa me fera faire une requête pour récupérer la date la plus ancienne et l'injecter dans une nouvelle requête
misakilou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/06/2011, 17h12   #15
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par misakilou Voir le message
parce que sa me fera faire une requête pour récupérer la date la plus ancienne et l'injecter dans une nouvelle requête

Les sous requêtes sont prises en charge maintenant sous MySQL
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h23.


 
 
 
 
Partenaires

Hébergement Web