119 votes

Sélection de mySQL basée uniquement sur le mois et l'année

J'ai une colonne dans ma base de données MySQL qui contient quelques lignes. L'une de ces lignes est une DATE, comme ceci : 2012-02-01

Ce que je veux réaliser, c'est faire un SELECT avec PHP basé uniquement sur l'année et le mois.

La logique du SELECT sera la suivante :

$q="SELECT * FROM projects WHERE Date="SELECT HERE THE SPECIFIC YEAR AND MONTH"";

Le mois et l'année spécifiques seront transmis à partir d'un fichier de type $_POST comme ceci $_POST['period']="2012-02";

Comment puis-je le faire ?

2 votes

Vous pouvez utiliser l'instruction BETWEEN

234voto

Rick Kuipers Points 6348
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5

9 votes

Votre requête n'évoluera pas car elle doit effectuer un balayage complet de la table, à moins qu'il n'existe une optimisation dans MySQL dont je ne suis pas au courant.

3 votes

Est-ce vrai pour EXTRACT(YEAR_MONTH FROM Date) ?

20voto

ypercube Points 62714

Si vous avez

$_POST['period'] = "2012-02";

Tout d'abord, trouvez le premier jour du mois :

$first_day = $_POST['period'] . "-01"

Alors cette requête utilisera un index sur Date si vous en avez un :

$q = "
    SELECT *  
    FROM projects 
    WHERE Date BETWEEN '$first_day' 
                   AND LAST_DAY( '$first_day' )
     " ;

On pourrait également utiliser des intervalles inclusifs-exclusifs, qui fonctionnent assez bien (vous n'avez pas à vous soucier de savoir si la colonne est DATE , DATETIME o TIMESTAMP ni sur la précision :

$q = "
    SELECT *  
    FROM projects 
    WHERE Date >= '$first_day' 
      AND Date  < '$first_day' + INTERVAL 1 MONTH 
     " ;

Avertissement de sécurité :

Vous devez échapper correctement ces valeurs ou utiliser des déclarations préparées. En bref, utilisez la méthode recommandée de nos jours en PHP, pour éviter tout problème d'injection SQL.

2 votes

Oui, +1 pour l'intervalle, j'utilisais initialement les fonctions Année + Mois, mais celles-ci n'étaient pas mises à l'échelle et n'utilisaient pas d'index.

0 votes

@sobelito Oui. Je préfère généralement les intervalles inclusifs-exclusifs. Poste mis à jour.

2 votes

Veuillez échapper à ces valeurs ou utiliser des déclarations préparées...

11voto

Arjan Points 5346
$q="SELECT * FROM projects WHERE YEAR(date) = 2012 AND MONTH(date) = 1;

9voto

aefxx Points 10941

Voilà. Laissez l'informatique à PHP et épargnez du travail à votre base de données. De cette façon, vous pouvez utiliser efficacement un index sur le fichier Date colonne.

<?php
    $date = $_POST['period'];

    $start = strtotime($date);
    $end   = strtotime($date . ' 1 month - 1 second');

    $query = sprintf(
        'SELECT *
           FROM projects
          WHERE Date BETWEEN FROM_UNIXTIME(%u) AND FROM_UNIXTIME(%u)',
        $start,
        $end
    );

EDIT
J'ai oublié la conversion de l'horodatage Unix.

0 votes

Il est compatible avec les index, mais strtotime vous donne int et vous devez d'abord le convertir en date pour mysql.

0 votes

Ce devrait être une concaténation de chaînes de caractères, plutôt qu'une opération de somme : $end = strtotime($date .' 1 month - 1 second');

9voto

nazmulhaqued Points 11

Supposons que vous avez un champ de base de données created_at où vous prenez la valeur de l'horodatage. Vous souhaitez effectuer une recherche par année et mois à partir de la date created_at.

YEAR(date(created_at))=2019 AND MONTH(date(created_at))=2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X