Seleccione mySQL basado solo en mes y año

102

Tengo una columna en mi base de datos mySQL que tiene algunas filas. Una de esta fila es una FECHA, como esta:2012-02-01

Lo que quiero lograr es hacer un SELECT con PHP basado solo en el año y el mes.

La lógica del SELECT será la siguiente:

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

El mes y año específicos se pasarán de una $_POSTvariable, como esta$_POST['period']="2012-02";

¿Cómo puedo hacerlo?

DiegoP.
fuente
2
Puede usar la declaración BETWEEN
Ben Carey

Respuestas:

208
SELECT * FROM projects WHERE YEAR(Date) = 2011 AND MONTH(Date) = 5
Rick Kuipers
fuente
5
Su consulta no se escalará porque necesita hacer un escaneo completo de la tabla a menos que haya alguna optimización en MySQL de la que no tenga conocimiento.
aefxx
2
¿Es esto cierto para EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley
19

Si usted tiene

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

Primero, encuentre el primer día del mes:

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

Entonces esta consulta usará un índice Datesi tiene uno:

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

También se podrían usar intervalos inclusivos-exclusivos, que funcionan bastante bien (no tiene que preocuparse si la columna es DATE, DATETIMEo TIMESTAMP, ni por la precisión:

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

Advertencia de seguridad:

Debe escapar correctamente de estos valores o utilizar declaraciones preparadas. En resumen, use cualquier método recomendado en estos días en PHP, para evitar cualquier problema de inyección de SQL.

ypercubeᵀᴹ
fuente
2
Sí, +1 para el medio, inicialmente estaba usando las funciones Año + Mes, pero no se escalaron ni usaron índices.
sobelito
@sobelito Sí. Normalmente prefiero los intervalos inclusivos-exclusivos. Publicación actualizada.
ypercubeᵀᴹ
Por favor, evite estos valores o use declaraciones preparadas ... 😓
Jared
9

Aqui tienes. Deje la informática a PHP y guarde su DB algo de trabajo. De esta manera, puede hacer un uso efectivo de un índice en la Datecolumna.

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

EDITAR
Olvidé la conversión de la marca de tiempo de Unix.

aefxx
fuente
Es compatible con índices, pero strtotime le da int y primero debe convertirlo a la fecha para mysql.
piotrm
Debería ser una concatenación de cadenas, en lugar de una operación de suma:$end = strtotime($date .' 1 month - 1 second');
Konstantin Pereiaslov
6
$q="SELECT * FROM projects WHERE YEAR(date) = 2012 AND MONTH(date) = 1;
Arjan
fuente
6

Suponga que tiene un campo de base de datos created_at donde toma valor de la marca de tiempo. Quiere buscar por año y mes desde la fecha de creación.

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

Aquí, ENCUENTRE registro por MES y FECHA en mySQL

Aquí está su valor POST $_POST['period']="2012-02";

Solo, explota valor por guión $Period = explode('-',$_POST['period']);

Obtener matriz del valor de explosión:

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

Poner valor en la consulta SQL:

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

Obtenga el resultado por MES y AÑO.

chintan mahant
fuente
2

para obtener los valores de mes y año de la columna de fecha

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

Puedes hacer así:

$q="SELECT * FROM projects WHERE Year(Date) = '$year' and Month(Date) = '$month'";
Andreas Helgegren
fuente
1
Esto tampoco usa un índice
Thijs Riezebeek
1

La lógica será:

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

El LIKEoperador seleccionará todas las filas que comienzan con $_POST['period']seguido de un guión y el día del mes

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Alguna información adicional

Hristo Petev
fuente
4
-1 Operaciones de cadena en datos representados internamente como un entero !? ¿Hablas en serio?
aefxx
@Yaroslav Sí, muy eficiente, supongo: D
aefxx
2
Sin índice. Primero convierte el valor de la fecha en una cadena y luego coincide con esa cadena. En MySQL, cualquier tipo de columna puede ser consultado por LIKE. Pero aún así funcionará: D
Yaroslav
2
¿Alguien quiere mesas pequeñas?
Rob
No hay necesidad de estar loco por el rendimiento todo el tiempo, ¿verdad? A veces, el esfuerzo y el tiempo que le dedicas a algo para que funcione un par de microsegundos más rápido no hace ninguna diferencia, pero perdiste ese tiempo.
Hristo Petev
0

Aquí hay una consulta que utilizo y devolverá cada registro dentro de un período como una suma.

Aquí está el código:

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

Aquí se enumeran cada emp_nr y la suma de las horas mensuales que han acumulado.

Frank Casser
fuente
0

puede hacerlo cambiando $ q a esto:

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

Sí, esto está funcionando, pero devuelve una fila solo mientras hay varias filas para recuperar usando solo las columnas seleccionadas. Al igual que SELECT Title, Date FROM mytable DONDE AÑO (Fecha) = 2017 Y MES (Fecha) = 09 devuelve solo una fila.

BLOGBIR
fuente