Wählen Sie mySQL nur basierend auf Monat und Jahr

102

Ich habe eine Spalte in meiner mySQL-Datenbank, die einige Zeilen enthält. Eine dieser Zeilen ist ein DATUM wie folgt:2012-02-01

Was ich erreichen möchte, ist ein SELECT mit PHP nur basierend auf Jahr und Monat.

Die Logik von SELECT lautet wie folgt:

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

Der spezifische Monat und das Jahr werden von einer $_POSTVariablen wie dieser übergeben$_POST['period']="2012-02";

Wie kann ich es tun?

DiegoP.
quelle
2
Sie können die ZWISCHEN Anweisung verwenden
Ben Carey

Antworten:

208
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5
Rick Kuipers
quelle
5
Ihre Abfrage wird nicht skaliert, da ein vollständiger Tabellenscan durchgeführt werden muss, es sei denn, es gibt eine Optimierung in MySQL, die mir nicht bekannt ist.
Aefxx
2
Ist das wahr für EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley
19

Wenn Sie haben

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

Finden Sie zuerst den ersten Tag des Monats:

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

Diese Abfrage verwendet dann einen Index für, Datefalls Sie einen haben:

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

Man könnte auch inclusive-exklusive Intervalle verwenden, die ziemlich gut arbeiten (Sie müssen nicht zu kümmern , wenn die Spalte DATE, DATETIMEoder TIMESTAMP, noch über die Genauigkeit:

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

Sicherheitswarnung:

Sie sollten diese Werte ordnungsgemäß umgehen oder vorbereitete Anweisungen verwenden. Kurz gesagt, verwenden Sie die heutzutage in PHP empfohlene Methode, um Probleme mit der SQL-Injektion zu vermeiden.

ypercubeᵀᴹ
quelle
2
Ja, +1 für zwischendurch, ich habe anfangs Funktionen für Jahr + Monat verwendet, aber solche haben weder skaliert noch Indizes verwendet.
Sobelito
@sobelito Ja. Normalerweise bevorzuge ich die Inklusiv-Exklusiv-Intervalle. Beitrag aktualisiert.
Ypercubeᵀᴹ
Bitte entkommen Sie diesen Werten oder verwenden Sie vorbereitete Anweisungen ... 😓
Jared
9

Bitte schön. Überlassen Sie den Computer PHP und sparen Sie Ihrer DB etwas Arbeit. Auf diese Weise können Sie einen Index für die DateSpalte effektiv nutzen .

<?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
    );

BEARBEITEN
Die Unix-Zeitstempelkonvertierung wurde vergessen.

aefxx
quelle
Es ist indexfreundlich, aber strtotime gibt Ihnen int und Sie müssen es zuerst für MySQL auf das Datum konvertieren.
Piotrm
Es sollte eher eine Zeichenfolgenverkettung als eine $end = strtotime($date .' 1 month - 1 second');
Summenoperation sein
6
$q="SELECT * FROM projects WHERE YEAR(date) = 2012 AND MONTH(date) = 1;
Arjan
quelle
6

Angenommen, Sie haben ein Datenbankfeld created_at, in dem Sie den Wert aus dem Zeitstempel entnehmen. Sie möchten ab Erstellungsdatum nach Jahr und Monat suchen.

YEAR(date(created_at))=2019 AND MONTH(date(created_at))=2
nazmulhaqued
quelle
3

Hier finden Sie die Aufzeichnung nach MONAT und DATUM in mySQL

Hier ist Ihr POST-Wert $_POST['period']="2012-02";

Explodieren Sie den Wert einfach per Bindestrich $Period = explode('-',$_POST['period']);

Array vom Explosionswert abrufen:

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

Wert in SQL Query einfügen:

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

Erhalten Sie das Ergebnis von MONAT und JAHR.

Chintan Mahant
quelle
2

um die Monats- und Jahreswerte aus der Datumsspalte abzurufen

select year(Date) as "year", month(Date) as "month" from Projects
PAULDAWG
quelle
2

Sie können dies tun:

$q="SELECT * FROM projects WHERE Year(Date) = '$year' and Month(Date) = '$month'";
Andreas Helgegren
quelle
1
Dies verwendet auch keinen Index
Thijs Riezebeek
1

Die Logik wird sein:

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

Der LIKEBediener wählt alle Zeilen aus, die mit $_POST['period']dem Bindestrich und dem Tag des Mont beginnen

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Einige zusätzliche Informationen

Hristo Petev
quelle
4
-1 String-Operationen für Daten, die intern als Ganzzahl dargestellt werden!? Meinst du das ernst?
Aefxx
@ Jaroslaw Ja, sehr effizient, ich nehme an: D
aefxx
2
Ohne Index. Es konvertiert zuerst den Datumswert in eine Zeichenfolge und stimmt dann mit dieser Zeichenfolge überein. In MySQL kann jeder Spaltentyp von LIKE abgefragt werden. Aber es wird trotzdem funktionieren: D
Jaroslaw
2
Kleine Bobby Tische jemand?
Rob
Sie müssen nicht die ganze Zeit verrückt nach Leistung sein, oder? Manchmal macht der Aufwand und die Zeit, die Sie investieren, damit es ein paar Mikrosekunden schneller funktioniert, keinen Unterschied, aber Sie haben diese Zeit verloren.
Hristo Petev
0

Hier ist eine Abfrage, die ich verwende und die jeden Datensatz innerhalb eines Zeitraums als Summe zurückgibt.

Hier ist der Code:

$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();
?>

Dies listet jedes emp_nr und die Summe der monatlichen Stunden auf, die sie angesammelt haben.

Frank Casser
quelle
0

Sie können dies tun, indem Sie $ q in Folgendes ändern:

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

Ja, das funktioniert, aber es wird nur eine Zeile zurückgegeben, während mehrere Zeilen nur mit ausgewählten Spalten abgerufen werden können. Wie bei SELECT Title gibt Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09 nur eine Zeile zurück.

BLOGBIR
quelle