IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Group By sur une periode


Sujet :

Requêtes MySQL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 10
    Par défaut Group By sur une periode
    Bonjour,
    Je n'arrive pas de trouver une solution simple pour mon probleme,
    J'ai une bdd avec deux colonnes:
    time(datatime) et value(tinyint)
    2017-10-04 17:50:10 = 1
    2017-10-05 17:20:10 = 2
    2018-11-04 17:45:10 = 1
    2018-10-04 16:50:10 = 5
    ...

    actuellement je groupe les values par année (ça me pose pas de probleme)
    2017=49
    2018=56
    ...

    Je voudrais les grouper par période donnée : (année=mois janvier à août + année-1=mois septembre à décembre)
    mais la je ne sais pas comment faire.
    2015/2016=xx
    2016/2017=xx
    2017/2018=xx
    ...

    merci pour votre aide.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Groupez par dateadd(month, -4, <votre datetime>)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 10
    Par défaut
    Merci mais j’obtiens une seul ligne avec la somme total:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT year('time') As annee, date_add('time', INTERVAL -4 MONTH) AS periode, sum('value') AS qty
    FROM 'conso'
    GROUP BY periode
    merci pour votre aide

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il faut ajuster un peu (a priori je vous ai donné le mauvais sens), mais c'est l'idée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    create table conso ( col_time   datetime,    col_value   tinyint)
    go
     
    insert into conso (col_time, col_value) values
    ('2017-01-01 17:50:10', 1),
    ('2017-02-01 17:50:10', 2),
    ('2017-03-01 17:50:10', 3),
    ('2017-04-01 17:50:10', 4),
    ('2017-05-01 17:50:10', 5),
    ('2017-06-01 17:50:10', 6),
    ('2017-07-01 17:50:10', 7),
    ('2017-08-01 17:50:10', 8),
    ('2017-09-01 17:50:10', 9),
    ('2017-10-01 17:50:10', 10),
    ('2017-11-01 17:20:10', 11),
    ('2017-12-01 17:45:10', 12),
    ('2018-01-02 17:50:10', 10),
    ('2018-02-02 17:50:10', 20),
    ('2018-03-02 17:50:10', 30),
    ('2018-04-02 17:50:10', 40),
    ('2018-05-02 17:50:10', 50),
    ('2018-06-02 17:50:10', 60),
    ('2018-07-02 17:50:10', 70),
    ('2018-08-02 17:50:10', 80),
    ('2018-09-02 17:50:10', 90),
    ('2018-10-02 17:50:10', 100),
    ('2018-11-02 17:20:10', 110),
    ('2018-12-02 17:45:10', 120)
    go
     
      select min(convert(varchar(6), col_time, 112)) as periode_min
           , max(convert(varchar(6), col_time, 112)) as periode_max
           , sum(col_value) as value_sum
        from conso
    group by year(dateadd(month, 4, col_time))
    Par contre, vous n'utilisez pas SQL-Server : l'utilisation de l'alias "periode" dans le group by, la fonction date_add, tout cela ressemble à MySQL.

    Qu'à cela ne tienne, c'est la logique plus que le dialecte qui est important ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      select min(date_format('time', '%Y%m')) as periode_min
           , max(date_format('time', '%Y%m')) as periode_max
           , sum('value') as value_sum
        from 'conso'
    group by year(date_add('time', INTERVAL 4 MONTH))

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 10
    Par défaut
    Bonjour,
    Merci pour votre aide mais je reçois comme résultat:

    periode_min -periode_max - value_sum
    NULL - NULL - 0

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il n'y a pas de raison que votre requête renvoie des données et la mienne des nulls, ou alors votre table a été nettoyée entre temps.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 10
    Par défaut
    Bonjour,
    C'est quoi le 112 dans votre requête ?
    select min(convert(varchar(6), col_time, 112)) as periode_min...

    merci

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par rems02 Voir le message
    C'est quoi le 112 dans votre requête ?
    Citation Envoyé par Waldar Voir le message
    Par contre, vous n'utilisez pas SQL-Server : l'utilisation de l'alias "periode" dans le group by, la fonction date_add, tout cela ressemble à MySQL.
    J'apprécierai que vous lisiez en entier les réponses qui vous sont faites et pas simplement copier / coller le code, l'exécuter et dire "ça marche pas".

    Vous avez posté dans le forum MS SQL-Server, je vous ai fait une réponse SQL-Server. Le 112 est un type de conversion de date :
    http://www.sql-server-helper.com/tips/date-formats.aspx

    Mais comme a priori vous vous êtes trompé de forum, je vous ai aussi fait une réponse MySQL.

    Si vous me l'aviez confirmé ou infirmé, j'aurai pu déplacer la discussion au bon endroit.
    Mais comme ce n'était pas du code...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 10
    Par défaut
    Bonjour,
    J'utilise bien MySQL, dsl je n'ai pas fait attention d'erreur de forum, vous pouvez le deplacer.Merci
    J'ai bien testé votre code (avant bien sur j'essaie de comprendre )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select min(date_format('time', '%Y%m')) as periode_min
           , max(date_format('time', '%Y%m')) as periode_max
           , sum('value') as value_sum
        from 'conso'
    group by year(date_add('time', INTERVAL 4 MONTH))
    mais bisarement j'obtien bien la reponse NULL, et ma bdd est bien remplie.

    J'ai même essayer de faire un simple select avec la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select min(date_format('time', '%Y%m')) as periode_min , sum('value') as value_sum  from 'conso'
    mais toujours la meme chose.
    Merci bcp pour votre aide

  10. #10
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 443
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 443
    Par défaut
    Salut rems02.

    Ne vous trompez pas de forum car les réponses peuvent être totalement différentes.

    Citation Envoyé par rems02
    Je voudrais les grouper par période donnée : (année=mois janvier à août + année-1=mois septembre à décembre)
    La solution proposée par Waldar est fausse et il ne sait pas comment résoudre ce problème !

    Il ne s'agit pas de soustraire 4 mois à la date pour avoir la bonne période. Je m'explique à ce sujet.
    Vous demandez à ce que votre nouvelle période de douze mois, commence l'année précédente en septembre et fini l'année suivante en aout.
    Or une année même décalée, doit obligatoirement commencer en janvier.
    Donc comment passer de septembre à janvier ?

    Voici la convention où l'ancienne période devient la nouvelle période :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    +------------------+------------------+
    | Nouvelle période | Ancienne période |
    +------------------+------------------+
    |      Janvier     |    Septembre     |
    |      Fevrier     |      Octobre     |
    |         Mars     |     Novembre     |
    |        Avril     |     Décembre     |
    |          Mai     |      Janvier     |
    |         Juin     |      Fevrier     |
    |      Juillet     |         Mars     |
    |         Aout     |        Avril     |
    |    Septembre     |          Mai     |
    |      Octobre     |         Juin     |
    |     Novembre     |      Juillet     |
    |     Décembre     |         Aout     |
    +------------------+------------------+
    Pour faire coïncider septembre à janvier, il faut retrancher 8 mois !
    Janvier c'est 1 et septembre c'est 9, donc 9 - 1 = 8.

    Ensuite, vous désirez indiquer deux années, celle de l'année précédente et de l'année courante.
    Dans la nouvelle période, l'année sera nécessairement la même, c'est-à-dire l'année précédente.
    Il est inutile de recherche le min et le max, qui va compliquer la requête inutilement.

    J'ai mis votre ancienne requête, celle basée sur year(col_time).
    J'ai décomposé la requête en deux, car dans ce que je propose, il y a une sous-requête, à cause du fait que vous désirez faire apparaitre la période à cheval sur deux année.

    Voici ce que ce vous propose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`        integer unsigned  NOT NULL auto_increment PRIMARY KEY,
      `col_time`  datetime          NOT NULL,
      `col_value` tinyint           NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`col_time`,`col_value`) values
      ('2017-01-01 17:50:10',   1),
      ('2017-02-01 17:50:10',   2),
      ('2017-03-01 17:50:10',   3),
      ('2017-04-01 17:50:10',   4),
      ('2017-05-01 17:50:10',   5),
      ('2017-06-01 17:50:10',   6),
      ('2017-07-01 17:50:10',   7),
      ('2017-08-01 17:50:10',   8),
      ('2017-09-01 17:50:10',   9),
      ('2017-10-01 17:50:10',  10),
      ('2017-11-01 17:20:10',  11),
      ('2017-12-01 17:45:10',  12),
      ('2018-01-02 17:50:10',  10),
      ('2018-02-02 17:50:10',  20),
      ('2018-03-02 17:50:10',  30),
      ('2018-04-02 17:50:10',  40),
      ('2018-05-02 17:50:10',  50),
      ('2018-06-02 17:50:10',  60),
      ('2018-07-02 17:50:10',  70),
      ('2018-08-02 17:50:10',  80),
      ('2018-09-02 17:50:10',  90),
      ('2018-10-02 17:50:10', 100),
      ('2018-11-02 17:20:10', 110),
      ('2018-12-02 17:45:10', 120)
    --------------
     
    --------------
    select * from `test`
    --------------
     
    +----+---------------------+-----------+
    | id | col_time            | col_value |
    +----+---------------------+-----------+
    |  1 | 2017-01-01 17:50:10 |         1 |
    |  2 | 2017-02-01 17:50:10 |         2 |
    |  3 | 2017-03-01 17:50:10 |         3 |
    |  4 | 2017-04-01 17:50:10 |         4 |
    |  5 | 2017-05-01 17:50:10 |         5 |
    |  6 | 2017-06-01 17:50:10 |         6 |
    |  7 | 2017-07-01 17:50:10 |         7 |
    |  8 | 2017-08-01 17:50:10 |         8 |
    |  9 | 2017-09-01 17:50:10 |         9 |
    | 10 | 2017-10-01 17:50:10 |        10 |
    | 11 | 2017-11-01 17:20:10 |        11 |
    | 12 | 2017-12-01 17:45:10 |        12 |
    | 13 | 2018-01-02 17:50:10 |        10 |
    | 14 | 2018-02-02 17:50:10 |        20 |
    | 15 | 2018-03-02 17:50:10 |        30 |
    | 16 | 2018-04-02 17:50:10 |        40 |
    | 17 | 2018-05-02 17:50:10 |        50 |
    | 18 | 2018-06-02 17:50:10 |        60 |
    | 19 | 2018-07-02 17:50:10 |        70 |
    | 20 | 2018-08-02 17:50:10 |        80 |
    | 21 | 2018-09-02 17:50:10 |        90 |
    | 22 | 2018-10-02 17:50:10 |       100 |
    | 23 | 2018-11-02 17:20:10 |       110 |
    | 24 | 2018-12-02 17:45:10 |       120 |
    +----+---------------------+-----------+
    --------------
    select year(col_time) as annee,
           sum(col_value) as value
     from  test
    group by annee
    --------------
     
    +-------+-------+
    | annee | value |
    +-------+-------+
    |  2017 |    78 |
    |  2018 |   780 |
    +-------+-------+
    --------------
    select    year(col_time - interval 8 month) as decalage,
              sum(col_value)                    as qte
        from  test
    group by  decalage
    --------------
     
    +----------+------+
    | decalage | qte  |
    +----------+------+
    |     2016 |   36 |
    |     2017 |  402 |
    |     2018 |  420 |
    +----------+------+
    --------------
    select    concat(decalage, '/', decalage+1) as periode,
              qte
        from  (  select  year(col_time - interval 8 month) as decalage,
                         sum(col_value)                    as qte
                   from  test
               group by  decalage
              ) as x
    order by  decalage
    --------------
     
    +-----------+------+
    | periode   | qte  |
    +-----------+------+
    | 2016/2017 |   36 |
    | 2017/2018 |  402 |
    | 2018/2019 |  420 |
    +-----------+------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    J'espère avoir répondu à votre attente !

    @+

  11. #11
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 955
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 955
    Par défaut
    Citation Envoyé par rems02 Voir le message
    J'ai même essayer de faire un simple select avec la condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select min(date_format('time', '%Y%m')) as periode_min , sum('value') as value_sum  from 'conso'
    mais toujours la meme chose.
    Il y avait seulement une coquille dans la version mysql proposée par Waldar :
    from 'conso' à remplacer par from conso.
    Entre quote ('') c'est une chaine de caractères, et pas vos tables ou colonnes...

  12. #12
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    La solution proposée par Waldar est fausse et il ne sait pas comment résoudre ce problème !
    Vous noterez que j'ai remarqué l'erreur de ma première réponse et l'ai corrigé dans mon deuxième commentaire.
    Grouper par ANNEE(date - 8 mois) ou ANNEE(date + 4 mois), c'est strictement la même chose.

    Donc finalement vous faites une gros pavé pour proposer la même réponse à trois billes de syntaxe près.

    Oh, mais comme vous proposez la même réponse que moi, je peux affirmer que :
    La solution proposée par Artemus est fausse et il ne sait pas résoudre ce problème
    et comme vous je ne regarde pas votre code pour voir que si, ça donne le bon résultat ?

    Lisez tous les messages dans leur intégralité avant de prendre quelqu'un à parti.

    @skuatamad, merci pour la coquille de la quote. Ca devait être un ` qui s'est transformé en ' dans le message de l'auteur que j'ai bêtement repris.

Discussions similaires

  1. Count(*)/Group by sur une seule valeur
    Par Darkolive dans le forum Langage SQL
    Réponses: 3
    Dernier message: 19/03/2010, 22h56
  2. somme d'un champ sur une periode
    Par aldama dans le forum IHM
    Réponses: 5
    Dernier message: 08/05/2009, 16h02
  3. groupement de donnees sur une periode de temps
    Par ElBisounours dans le forum SQL
    Réponses: 5
    Dernier message: 12/06/2007, 11h59
  4. creation vue sur une periode
    Par LHERMITTE dans le forum Oracle
    Réponses: 2
    Dernier message: 30/03/2006, 11h46
  5. Un group by sur une fonction nvl
    Par Arkadius dans le forum Oracle
    Réponses: 3
    Dernier message: 21/10/2005, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo