Seleziona mySQL in base solo al mese e all'anno


102

Ho una colonna nel mio DB mySQL che ha alcune righe. Una di questa riga è una DATA, come questa:2012-02-01

Quello che voglio ottenere è fare una SELEZIONE con PHP basata solo sull'anno e sul mese.

La logica del SELECT sarà la seguente:

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

Il mese e l'anno specifici verranno passati da una $_POSTvariabile, come questa$_POST['period']="2012-02";

Come posso farlo?


2
Puoi usare la dichiarazione BETWEEN
Ben Carey

Risposte:


208
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5

5
La tua query non verrà ridimensionata perché deve eseguire una scansione completa della tabella a meno che non ci sia qualche ottimizzazione in MySQL di cui non sono a conoscenza.
aefxx

2
È vero per EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley

19

Se hai

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

Innanzitutto, trova il primo giorno del mese:

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

Quindi questa query utilizzerà un indice Datese ne hai uno:

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

Si potrebbe anche utilizzare intervalli esclusivi inclusivi, che funzionano abbastanza bene (non devi preoccuparti se la colonna è DATE, DATETIMEo TIMESTAMP, né della precisione:

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

Avviso di sicurezza:

È necessario sfuggire correttamente a questi valori o utilizzare istruzioni preparate. In breve, usa qualunque metodo sia consigliato in questi giorni in PHP, per evitare problemi di SQL injection.


2
Sì, +1 per tra, inizialmente stavo usando le funzioni Anno + Mese, ma queste non sono state ridimensionate, né utilizzate gli indici.
sobelito

@sobelito Yeah. Di solito preferisco gli intervalli inclusivi-esclusivi. Post aggiornato.
ypercubeᵀᴹ

Per favore evita questi valori o usa dichiarazioni preparate ... 😓
Jared

9

Ecco qui. Lascia l'elaborazione a PHP e salva un po 'di lavoro nel tuo DB. In questo modo puoi fare un uso efficace di un indice sulla Datecolonna.

<?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 Hai
dimenticato la conversione del timestamp Unix.


È indicizzato, ma strtotime ti dà int e devi prima convertirlo in data per mysql.
piotrm

Dovrebbe essere una concatenazione di stringhe, piuttosto che un'operazione di somma:$end = strtotime($date .' 1 month - 1 second');
Konstantin Pereiaslov

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

6

Supponiamo di avere un campo database created_at Dove prendi valore dal timestamp. Si desidera effettuare la ricerca per anno e mese dalla data di creazione_alla data.

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

3

Qui, TROVA record per MESE e DATA in mySQL

Ecco il tuo valore POST $_POST['period']="2012-02";

Basta esplodere il valore per trattino $Period = explode('-',$_POST['period']);

Ottieni array dal valore di esplosione:

Array ( [0] => 2012 [1] => 02 )

Metti valore in SQL Query:

SELECT * FROM projects WHERE YEAR(Date) = '".$Period[0]."' AND Month(Date) = '".$Period[0]."';

Ottieni risultati per MESE e ANNO.


2

per ottenere i valori del mese e dell'anno dalla colonna della data

select year(Date) as "year", month(Date) as "month" from Projects


1

La logica sarà:

SELECT * FROM objects WHERE Date LIKE '$_POST[period]-%';

L' LIKEoperatore selezionerà tutte le righe che iniziano con $_POST['period']seguito da un trattino e il giorno del mese

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Alcune informazioni aggiuntive


4
-1 Operazioni su stringhe sui dati rappresentati internamente come un numero intero !? Sei serio?
aefxx

@Yaroslav Sì, altamente efficiente, suppongo: D
aefxx

2
Senza indice. Per prima cosa converte il valore della data in stringa e poi corrisponde a quella stringa. In MySQL è possibile interrogare qualsiasi tipo di colonna con LIKE. Ma funzionerà ancora: D
Yaroslav

2
Tavolini da bobby chiunque?
Rob il

Non c'è bisogno di essere pazzi per le prestazioni tutto il tempo, ora lo fai. A volte lo sforzo e il tempo che dedichi a qualcosa per farlo funzionare un paio di microsecondi più velocemente non fa alcuna differenza, ma hai perso quel tempo.
Hristo Petev

0

Ecco una query che utilizzo e restituirà ogni record entro un periodo come somma.

Ecco il codice:

$result = mysqli_query($conn,"SELECT emp_nr, SUM(az) 
FROM az_konto 
WHERE date BETWEEN '2018-01-01 00:00:00' AND '2018-01-31 23:59:59' 
GROUP BY emp_nr ASC");

echo "<table border='1'>
<tr>
<th>Mitarbeiter NR</th>
<th>Stunden im Monat</th>
</tr>";

while($row = mysqli_fetch_array($result))
{
$emp_nr=$row['emp_nr'];
$az=$row['SUM(az)'];
echo "<tr>";
echo "<td>" . $emp_nr . "</td>";
echo "<td>" . $az . "</td>";
echo "</tr>";
}
echo "</table>";
$conn->close();
?>

Elenca ogni emp_nr e la somma delle ore mensili accumulate.


0

puoi farlo cambiando $ q in questo:

$q="SELECT * FROM projects WHERE YEAR(date) = $year_v AND MONTH(date) = $month_v;

-1

Sì, funziona, ma restituisce solo una riga mentre ci sono diverse righe da recuperare utilizzando solo le colonne selezionate. Come SELECT Title, Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09 restituisce solo una riga.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.