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 :

Lister les 12 mois de l'année


Sujet :

Requêtes MySQL

  1. #1
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut Lister les 12 mois de l'année
    Bonjour

    J'ai créé une table en mysql qui permet de renseigner des informations sur des journaux informatiques, en précisant l'année et le mois de leur création:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE bd_nitra.Journal(
    id_journal INT( 11 ) NOT NULL AUTO_INCREMENT ,
    annee VARCHAR ( 4 ) NOT NULL,
    mois VARCHAR ( 10 ) NOT NULL,
    fichier VARCHAR ( 200 ),
    PRIMARY KEY ( id_journal )
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_bin;
    Je voudrais maintenant afficher ces journaux à l'utilisateur sous forme de liste suivant les 12 mois de l'année, c'est-à-dire :

    Mois Année Fichier
    1 Janvier 2018 Fichier1.pdf
    2 Février 2018 Fichier2.pdf
    3 Mars 2018 Fichier3.pdf
    ... ... ... ...
    12 Décembre 2018 Fichier12.pdf

    Donc il va classer les résultats en fonction des 12 mois de l'année, janvier, février, mars etc... jusqu'en décembre.

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    Bonjour,
    Pour avoir la liste des mois, il te faut… une table qui liste les mois.
    Accessoirement, j'aurai utilisé des numériques pour les colonnes mois/années, voir directement une colonne de type date (quitte à mettre le premier du mois à chaque fois).

    Tatayo.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 603
    Billets dans le blog
    10
    Par défaut
    Je confirme les propos de Tatayo et j'argumente :

    - utiliser un type "date" vous permettra de contrôler automatiquement la validité du contenu
    - utiliser un type "date" vous donnera accès à toutes les fonctions liées au type date, ce qu'aucun autre type ne permet
    - utiliser du varchar court (ici 4 et 10 caractères) est contre performant. Pour des tailles réduites, du char est préférable : le varchar provoque parfois des désorganisations des pages de données et d'index lors des mises à jour et le varchar nécessite un réalignement préalable pour les opérations de tri et groupage, contrairement au char.
    - utiliser du varchar pour un contenu qui ne varie pas (ici l'année qui est toujours sur 4 caractères) est également contre-performant, la taille effective de la colonne sera supérieure à celle occupée par du char(4) !

  4. #4
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    Ok j'ai suivi vos conseils. En fait je ne voulais pas utiliser le type YEAR car je me retrouvais avec des résultats du type:

    Mais j'ai vu qu'il est possible d'extraire juste l'année en faisant par exemple ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT YEAR (annee) FROM Journal
    Mais cette fois-ci je me retrouve avec ce message d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.sql.SQLException: Column 'annee' not found.
    Pourtant j'ai bien créé la colonne annee:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE bd_nitra.Journal(
    id_journal INT( 11 ) NOT NULL AUTO_INCREMENT ,
    annee YEAR NOT NULL,
    mois TINYINT ( 2 ) NOT NULL,
    fichier VARCHAR ( 200 ),
    PRIMARY KEY ( id_journal )
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_bin;
    Concernant le mois, j'ai pris TINYINT tout d'abord parce qu'il prend mois d'espace en mémoire que les autres types numériques, et qu'ensuite j'ai trouvé une astuce toute simple pour lister mon tableau en fonction de l'ordre des 12 mois de l'année.
    Lors de l'insertion des mois la BD, au lieu d'insérer les mois de l'année, j'insère des numéros croissant allant de 1 à 12:

    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
    <select class="form-control" name="mois">
                 <option value="choix" >Choisissez le mois</option>
                 <option value="1">Janvier</option>
                 <option value="2">Février</option>
                 <option value="3">Mars</option>
                 <option value="4">Avril</option>
                 <option value="5">Mai</option>
                 <option value="6">Juin</option>
                 <option value="7">Juillet</option>
                 <option value="8">Août</option>
                 <option value="9">Septembre</option>
                 <option value="10">Octobre</option>
                 <option value="11">Novembre</option>
                 <option value="12">Décembre</option>
    	 </select>
    Du coup, je peux trier mes résultats par ordre croissant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id_journal, annee, mois, fichier FROM Journal WHERE ORDER BY mois
    Et dans mon code jquery, je remplace chaque entier par le mois qui correspond:

    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
     
    switch (mois) { 
    	case '1': 
    		mois = 'Janvier';
    		break;
    	case '2': 
    		mois = 'Février';
    		break;
    	case '3': 
    		mois = 'Mars';
    		break;		
    	case '4': 
    		mois = 'Avril';;
    		break; 
            case '5': 
                    mois = 'Mais';;
                    break; 
    	case '6': 
    		mois = 'Juin';
    		break;
    	case '7': 
    		mois = 'Juillet';
    		break;		
    	case '8': 
    		mois = 'Août';;
    		break;
            case '9': 
                    mois = 'Septembre';
                    break;
    	case '10': 
    		mois = 'Octobre';
    		break;
    	case '11': 
    		mois = 'Novembre';
    		break;		
    	case '12': 
    		mois = 'Décembre';;
    		break;
    	default:
    		console.log("");
            }
    Et ça marche, sauf que le format de l'année s'affiche en 2018-01-01, et quand je fais ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id_journal, YEAR(annee), mois, fichier FROM Journal WHERE annee = ? ORDER BY mois
    J'ai le message d'erreur suivant:

    java.sql.SQLException: Column 'annee' not found.

  5. #5
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    Pourquoi ne pas utiliser le type DATE (et non year), comme on te l'a proposé ?
    Avec une seule colonne tu peux faire ceci:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select year(col_date),month(col_date)
    from LaTable
    where ...

    Et pour les mois, tu peux très bien utiliser une table, ce qui te permet d'ailleurs de gérer plusieurs langues sans problème:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select year(col_date),month(col_date),mois.libelle
    from LaTable
    inner join mois on mois.num = month(LaTable.Col_date) and mois.langue = 'FR'
    where ...


    Tatayo.

  6. #6
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    J'ai essayé le type DATE:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE bd_nitra.Journal(
    id_journal INT( 11 ) NOT NULL AUTO_INCREMENT ,
    annee DATE NOT NULL,
    mois TINYINT ( 2 ) NOT NULL,
    fichier VARCHAR ( 200 ),
    PRIMARY KEY ( id_journal )
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_bin;
    Mais lors de l'insertion de l'année 2018 par exemple, j'ai le message suivant:

    Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect date value: '2018' for column 'annee' at row 1

  7. #7
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    Bon apparemment lors de l'insertion, il fallait que je concatène l'année avec le mois et le jour pour avoir le type de DATE, j'ai donc rajouté "-00-00" à l'année:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     String annee = getValeurChamp( request, CHAMP_ANNEE )+"-00-00";
    Mais lors du select:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT  YEAR(annee) FROM Journal
    J'ai toujours le message d'erreur:

    java.sql.SQLException: Column 'annee' not found.

  8. #8
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    C'est normal, le type DATE attend une date, pas une année.
    Il s'agit donc de remplacer les deux colonnes années et mois par une seule colonne, quitte comme je l'indiquais dans ma première réponse à y mettre le premier jour du mois.

    Tatayo.

  9. #9
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    Ok j'ai fait comme tu m'as dit mais j'ai plus fait une concaténation lors de l'insertion:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     String annee = getValeurChamp( request, CHAMP_ANNEE )+"-00-00";
    Et ça marche, mais lors du select:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT  YEAR(annee) FROM Journal
    J'ai toujours le message d'erreur:

    java.sql.SQLException: Column 'annee' not found.

  10. #10
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    Le message indique que la colonne annee n'existe pas dans la table journal… Donc là ce n'est plus un problème de format, de type de données ou autre, mais bien un problème de structure.
    A moins que le message soit erroné.

    Maintenant je ne comprends pas pourquoi tu restes sur une année "sans jour ni mois", et une colonne mois à côté. Pourquoi ne pas mettre une date valide dans la colonne, avec la vraie année, le vrai mois et 01 comme jour ?
    Ainsi que l'indiquais Escartefigue tu auras l'assurance d'avoir une date valide, tu pourras utiliser les fonctions liées aux dates, etc…

    Par exemple la recherche des journaux sur les x derniers mois est triviale à faire avec une colonne de type date, mais "un peu" plus compliquée avec 2 colonnes séparées.

    Tatayo.

  11. #11
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    J'ai choisi de créer la colonne mois à part pour pouvoir lister les mois suivant l'ordre des 12 mois de l'année: janvier, février, mars etc...Décembre. Donc avec cette méthode ça marche.

    Maintenant en créant une seule colonne pour l'année et le mois, je ne sais pas comment le faire.

  12. #12
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    Un tri sur une colonne de type date se fera naturellement sur l'année, le mois puis le jour. Mais rien n'empêche de trier sur une partie de la date, par exemple le mois:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    selectFromWhereorder by month(LaColonne)
    De la même façon tu peux faire un groupage sur le mois:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select sum(UneColonne),Month(ColonneDate)
    from latable
    wheregroup by month(ColonneDate)

    Tatayo.

  13. #13
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 886
    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 : 6 886
    Par défaut
    Salut à tous.

    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
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `journal`
    --------------
     
    --------------
    CREATE TABLE `journal`
    ( `id`       integer  unsigned NOT NULL auto_increment primary key,
      `date`     date              NOT NULL,
      `fichier`  varchar(255)      NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `journal` (`date`,`fichier`) values
      ('2018-01-01', 'fichier_01.pdf'),
      ('2018-02-01', 'fichier_02.pdf'),
      ('2018-03-01', 'fichier_03.pdf'),
      ('2018-04-01', 'fichier_04.pdf'),
      ('2018-05-01', 'fichier_05.pdf'),
      ('2018-06-01', 'fichier_06.pdf'),
      ('2018-07-01', 'fichier_07.pdf'),
      ('2018-08-01', 'fichier_08.pdf'),
      ('2018-09-01', 'fichier_09.pdf'),
      ('2018-10-01', 'fichier_10.pdf'),
      ('2018-11-01', 'fichier_11.pdf'),
      ('2018-12-01', 'fichier_12.pdf')
    --------------
     
    --------------
    select * from `journal`
    --------------
     
    +----+------------+----------------+
    | id | date       | fichier        |
    +----+------------+----------------+
    |  1 | 2018-01-01 | fichier_01.pdf |
    |  2 | 2018-02-01 | fichier_02.pdf |
    |  3 | 2018-03-01 | fichier_03.pdf |
    |  4 | 2018-04-01 | fichier_04.pdf |
    |  5 | 2018-05-01 | fichier_05.pdf |
    |  6 | 2018-06-01 | fichier_06.pdf |
    |  7 | 2018-07-01 | fichier_07.pdf |
    |  8 | 2018-08-01 | fichier_08.pdf |
    |  9 | 2018-09-01 | fichier_09.pdf |
    | 10 | 2018-10-01 | fichier_10.pdf |
    | 11 | 2018-11-01 | fichier_11.pdf |
    | 12 | 2018-12-01 | fichier_12.pdf |
    +----+------------+----------------+
    --------------
    select    year(date),
              monthname(date),
              fichier
     
      from  `journal`
     
    order by date
    --------------
     
    +------------+-----------------+----------------+
    | year(date) | monthname(date) | fichier        |
    +------------+-----------------+----------------+
    |       2018 | janvier         | fichier_01.pdf |
    |       2018 | février         | fichier_02.pdf |
    |       2018 | mars            | fichier_03.pdf |
    |       2018 | avril           | fichier_04.pdf |
    |       2018 | mai             | fichier_05.pdf |
    |       2018 | juin            | fichier_06.pdf |
    |       2018 | juillet         | fichier_07.pdf |
    |       2018 | août            | fichier_08.pdf |
    |       2018 | septembre       | fichier_09.pdf |
    |       2018 | octobre         | fichier_10.pdf |
    |       2018 | novembre        | fichier_11.pdf |
    |       2018 | décembre        | fichier_12.pdf |
    +------------+-----------------+----------------+
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    @+

  14. #14
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    Finalement ça marche, j'ai pu trouver la source de l'erreur suivante:

    java.sql.SQLException: Column 'annee' not found.
    C'est au niveau de mon code Java. Je reçois le message d'erreur lorsque je précise le nom de colonne dans la méthode suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    journal.setAnnee( resultSet.getString( "annee") );
    J'ai donc remplacé le nom de colonne par l'index de la colonne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    journal.setAnnee( resultSet.getString( 1) );
    Donc je ne comprends pas pourquoi ça ne reconnait pas le nom de colonne, mais ça marche.

    J'ai donc supprimé la colonne "mois" comme vous me l'avez conseillé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE `journal`
    ( `id`       integer  unsigned NOT NULL auto_increment primary key,
      `annee`     date              NOT NULL,
      `fichier`  varchar(255)      NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    Par-contre la méthode monthname(date) m'affiche des entiers(1,2,3...12) à la place des mois (janvier, février,...):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id_journal, monthname(annee), fichier  FROM Journal WHERE YEAR(annee) = ? order by annee
    J'ai pourtant la date au format "0000-00-00" au niveau de la colonne annee.

    Merci

  15. #15
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 434
    Par défaut
    Pourquoi la colonne annee n'est pas trouvée ? C'est parce qu'elle n'existe pas dans le résultat.
    Il faut juste nommer la colonne dans le select pour que ça fonctionne:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select year(annee) as annee
    from LaTable
    Where
    Pour le reste je ne peux pas t'aider, je n'utilise ni java ni MySQL.

    Tatayo.

  16. #16
    Membre éclairé
    Inscrit en
    Juin 2005
    Messages
    578
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 578
    Par défaut
    Merci beaucoup pour votre aide, surtout à toi Tatayo.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/01/2017, 14h26
  2. Lister les mois-année entre deux dates données
    Par Andry dans le forum Langage
    Réponses: 9
    Dernier message: 16/03/2009, 08h37
  3. les mois de l'année
    Par hananemeryem dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 23/08/2007, 14h48
  4. [Astute] Les 12 mois de l'année
    Par Le Pharaon dans le forum VB 6 et antérieur
    Réponses: 19
    Dernier message: 01/08/2006, 15h28

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