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 13/06/2011, 23h19   #1
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Par défaut Select MAX d'une donnée de chaque jour

Bonjour à tous,

Je fais appel à vous car je sens que je suis en rupture...

Pour résumer, j'ai une table dans laquelle j'ai une colonne datetime, une colonne 'maDonnee', et d'autres colonnes de données (pas importante dans notre cas)

Je souhaite faire une requête qui me récupère la valeur MAX de 'maDonnee' de chaque jour d'un mois donné. Donc en gros 1 ligne / jour en sortie, avec la valeur max de maDonnee.

J'ai tenté plein de chose avec du MAX(date), du GROUP BY Day(date), MAX(maDonnee)... J'ai mixé un peu tout ça, mais je n'arrive pas au résultat voulu.

Auriez vous la gentillesse de me sortir de la souffrance ?

Merci d'avance.
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 07h30   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Bonjour,

Votre type Date, est-ce un timestamp (avec heure , minutes, secondes, etc) ou une date (avec juste année / mois / jour) ?

Sinon votre requete va ressembler a ceci :

Code :
1
2
3
4
5
 
SELECT maDate, max(maDonnée)
FROM ma_table
WHERE ....
GROUP BY maDate
Dans la close where il faut que vous gériez le mois qui vous interesse, mais pour ceci il faudrait que l'on connaisse votre SGBD et le type de votre date

De plus le group by pourrai changer si votre date est un timestamp.
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 09h10   #3
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Bonjour,

MySql, champ Datetime (YYYY-mm-dd hh:ii:ss)

Merci d'avance
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 09h41   #4
Membre éprouvé
 
Avatar de elbj
 
Inscription : novembre 2004
Messages : 339
Détails du profil
Informations personnelles :
Âge : 38
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : novembre 2004
Messages : 339
Points : 422
Points : 422
Bonjour

A partir d'une table test :
Code :
1
2
3
4
5
CREATE TABLE [MaTable](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[MaDate] [datetime] NULL,
	[MaDonnee] [int] NULL,
 CONSTRAINT [PK_MaTable] PRIMARY KEY)
J'ai réalisé vite fait un truc comme ça :
Code :
1
2
3
4
5
6
7
8
9
SELECT 
  YEAR(MaDate) AS Annee,
  MONTH(MaDate) AS Mois,
  MAX(MaDonnee) AS MaxDonnee
FROM MaTable MT
GROUP BY 
  YEAR(MaDate),
  MONTH(MaDate)
HAVING MAX(MaDonnee) = (SELECT MAX(MaDonnee) WHERE YEAR(MaDate) = YEAR(MT.MaDate) AND MONTH(MaDate) = MONTH(MT.MaDate))
A peaufinner

Test réalisé sous SQL Server, sous MySQL il faudra certainement remplacer les noms de fonctions. J'espère que ça fonctionnera.

+++
__________________
Christophe B.

Aide toi et www.developpez.com t'aidera !
Le Soleil se lève pour celui qui va à sa rencontre !
Le meilleurs moyen de prévoir le futur est encore de le créer !
elbj est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 14/06/2011, 10h01   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Il suffit d'arrondir la colonne datetime à la journée :
Code :
1
2
3
4
5
  SELECT DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
       , max(MaDonnee) AS MaDonnee
    FROM MaTable
   WHERE MaDate BETWEEN '2011-05-01' AND '2001-05-31'
GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
Si vous avez des jours sans données, ceux-ci seront absent de cette requête.
Il faut alors impérativement posséder une table calendrier dans votre modèle de données, et faire une jointure externe à partir de celle-ci.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 10h37   #6
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Citation:
Envoyé par Waldar Voir le message
Il suffit d'arrondir la colonne datetime à la journée :
Code :
1
2
3
4
5
  SELECT DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
       , max(MaDonnee) AS MaDonnee
    FROM MaTable
   WHERE MaDate BETWEEN '2011-05-01' AND '2001-05-31'
GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
Si vous avez des jours sans données, ceux-ci seront absent de cette requête.
Il faut alors impérativement posséder une table calendrier dans votre modèle de données, et faire une jointure externe à partir de celle-ci.
Merci à tous de vos réponses, je pense que ta solution Waldar se rapproche plus de ce que j'attends.

Mais je viens à mon avis de trouver mon problème de base, mon champ (maDonnee) est de type 'varchar', de ce fait il ne peut pas être traité comme un int. Y aurais t-il un moyen de forcer ça ?
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 10h49   #7
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
J'ai trouvé une partie de la réponse, il faut faire un CAST pour forcer en INT

Code :
1
2
3
4
5
  SELECT DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
       , max(MaDonnee) AS MaDonnee
    FROM MaTable
   WHERE MaDate BETWEEN '2011-05-01' AND '2001-05-31'
GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
Nouveau problème qui apparait, désormais j'ai une requête qui fait un IN de plusieurs ID (non uniques), de manière à grouper les lignes ayant le même ID. Nous cherchons toujours à faire la même opération, seulement dans le cas présent, il faut faire un SUM des colonnes 'maDonnee' des ID, j'ai testé ça, mais ça ne fonctionne pas :

Code :
1
2
3
4
5
  SELECT DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
       , max(sum(MaDonnee)) AS MaDonnee
    FROM MaTable
   WHERE MaDate BETWEEN '2011-05-01' AND '2001-05-31'
GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
Pourriez vous m'éclairer ? Merci encore
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 11h09   #8
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
Il suffit juste de passer par une table dérivée :
Code :
1
2
3
4
5
6
7
8
9
SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
            	, 	SUM(MaDonnee) AS MaDonnee
            FROM 	MaTable
            WHERE 	MaDate BETWEEN '2011-05-01' AND '2001-05-31'
            GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
        )	tmp
GROUP BY MaDate
__________________
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 14/06/2011, 12h03   #9
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Citation:
Envoyé par al1_24 Voir le message
Il suffit juste de passer par une table dérivée :
Code :
1
2
3
4
5
6
7
8
9
SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
            	, 	SUM(MaDonnee) AS MaDonnee
            FROM 	MaTable
            WHERE 	MaDate BETWEEN '2011-05-01' AND '2001-05-31'
            GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
        )	tmp
GROUP BY MaDate

Merci, je viens de tenter dans tous les sens, mais visiblement ça me sort la somme de 'maDonnee' sur chaque journée, et non la somme des valeurs MAX de chaque journée
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 12h07   #10
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Citation:
Envoyé par al1_24 Voir le message
Il suffit juste de passer par une table dérivée :
Code :
1
2
3
4
5
6
7
8
9
SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
            	, 	SUM(MaDonnee) AS MaDonnee
            FROM 	MaTable
            WHERE 	MaDate BETWEEN '2011-05-01' AND '2001-05-31'
            GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
        )	tmp
GROUP BY MaDate

J'ai compris en écrivant mon dernier message
Il suffit de grouper par date dans la table dérivée, et de grouper ensuite par jour dans la requête de base (je connais pas les termes exacts).
Ça donne un truc comme ça :

Code :
1
2
3
4
5
6
7
8
9
SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  date AS MaDate
            	, 	SUM(MaDonnee) AS MaDonnee
            FROM 	MaTable
            WHERE 	MaDate BETWEEN '2011-05-01' AND '2001-05-31'
            GROUP BY date
        )	tmp
GROUP BY Day(MaDate)
[/QUOTE]


Merci à tous
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 12h12   #11
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
Il ne faut pas oublier d'adapter le requête au besoin !


Code sql :
1
2
3
4
5
6
7
8
 SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
                ,     CAST(MaDonnee AS INTEGER) AS MaDonnee
            FROM     MaTable
            WHERE     MaDate BETWEEN '2011-05-01' AND '2001-05-31'
        )    tmp
GROUP BY MaDate


notamment, mettre le CASTet enlever le SUM
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 12h18   #12
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Citation:
Envoyé par dehorter olivier Voir le message
Il ne faut pas oublier d'adapter le requête au besoin !


Code sql :
1
2
3
4
5
6
7
8
 SELECT  MaDate
    ,   MAX(MaDonnee) AS MaDonnee
FROM    (   SELECT  DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
                ,     CAST(MaDonnee AS INTEGER) AS MaDonnee
            FROM     MaTable
            WHERE     MaDate BETWEEN '2011-05-01' AND '2001-05-31'
        )    tmp
GROUP BY MaDate


notamment, mettre le CASTet enlever le SUM

Merci de ta réponse, mais il faut effectivement un SUM je pense, car nous prenons plusieurs donnée dans la "requête dérivée"
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 12h23   #13
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
Je ne comprend pas. Dans ce message tu reprochais que la somme soit faite

Citation:
Envoyé par Subshadow Voir le message
Merci, je viens de tenter dans tous les sens, mais visiblement ça me sort la somme de 'maDonnee' sur chaque journée, et non la somme des valeurs MAX de chaque journée
et maintenant tu indiques le contraire ??????

Citation:
Merci de ta réponse, mais il faut effectivement un SUM je pense, car nous prenons plusieurs donnée dans la "requête dérivée"
dehorter olivier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 12h51   #14
Nouveau Membre du Club
 
Inscription : novembre 2007
Messages : 221
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 221
Points : 35
Points : 35
Non non, il y avais problème de compréhension car enfaite, je dois grouper des ID différents ( WHERE id IN(1,2,3)) qui ont plusieurs valeurs par jour.

Je souhaite sortir la somme des valeurs MAX par jour pour ce groupe.

Je sais, c'est pas très clair, mais je m'embrouille moi même
Dev@lone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/06/2011, 14h00   #15
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Je ne vois nulle part dans vos codes où vous gérez cette problématique.
À mon avis il faut essayer quelque chose de ce type-là :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  SELECT DATE_FORMAT(MaDate,%Y %m %d) AS MaDate
       , case
           when Id IN (1,2,3) then 'Groupe1'
           when Id IN (4,5,6) then 'Groupe2'
           when Id IN (7,8,9) then 'Groupe3'
         --  else 'Groupe0' -- Si besoin
         end AS groupe
       , max(cast(MaDonnee AS Integer)) AS MaDonnee
    FROM MaTable
   WHERE MaDate BETWEEN '2011-05-01' AND '2001-05-31'
     AND Id IN (1,2,3,4,5,6,7,8,9) -- Si besoin
GROUP BY DATE_FORMAT(MaDate,%Y %m %d)
       , case
           when Id IN (1,2,3) then 'Groupe1'
           when Id IN (4,5,6) then 'Groupe2'
           when Id IN (7,8,9) then 'Groupe3'
           else 'Groupe0'
         end;
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h05.


 
 
 
 
Partenaires

Hébergement Web