Selecione mySQL com base apenas no mês e ano


102

Eu tenho uma coluna em meu banco de dados mySQL que tem algumas linhas. Uma desta linha é uma DATE, assim:2012-02-01

O que pretendo alcançar é fazer um SELECT com PHP baseado apenas no ano e mês.

A lógica do SELECT será a seguinte:

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

O mês e ano específicos serão passados ​​de uma $_POSTvariável, como este$_POST['period']="2012-02";

Como eu posso fazer isso?


2
Você pode usar a declaração BETWEEN
Ben Carey de

Respostas:


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

5
Sua consulta não será escalada porque precisa fazer uma varredura completa da tabela, a menos que haja alguma otimização no MySQL que eu não conheço.
aefxx 01 de

2
Isso é verdade para EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley 01 de

19

Se você tem

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

Primeiro, encontre o primeiro dia do mês:

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

Então, esta consulta usará um índice, Datese você tiver um:

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

Também é possível usar intervalos inclusivos exclusivos, que funcionam muito bem (você não precisa se preocupar se a coluna é DATE, DATETIMEou TIMESTAMP, nem sobre a precisão:

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

Aviso de segurança:

Você deve escapar adequadamente desses valores ou usar instruções preparadas. Resumindo, use qualquer método recomendado atualmente em PHP, para evitar problemas de injeção de SQL.


2
Sim, +1 para o meio, eu inicialmente estava usando as funções Ano + Mês, mas não escalou, nem utilizou índices.
sobelito

@sobelito Sim. Eu geralmente prefiro os intervalos inclusivos exclusivos. Postagem atualizada.
ypercubeᵀᴹ

Por favor, escape desses valores ou use declarações preparadas ... 😓
Jared

9

Aqui está. Deixe a computação para o PHP e salve seu banco de dados algum trabalho. Dessa forma, você pode fazer uso eficaz de um índice na Datecoluna.

<?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
Esqueceu a conversão de carimbo de data / hora Unix.


É compatível com o índice, mas strtotime fornece int e você precisa primeiro convertê-lo em data para o mysql.
piotrm 01 de

Deve ser concatenação de string, em vez de operação de soma:$end = strtotime($date .' 1 month - 1 second');
Konstantin Pereiaslov

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

6

Suponha que você tenha um campo de banco de dados created_at Onde você obtém valor do carimbo de data / hora. Você deseja pesquisar por ano e mês a partir da data de criação.

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

3

Aqui, ENCONTRAR registro por MONTH e DATE em mySQL

Aqui está o seu valor POST $_POST['period']="2012-02";

Explodir o valor pelo traço $Period = explode('-',$_POST['period']);

Obtenha a matriz do valor de explosão:

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

Coloque valor na consulta SQL:

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

Obtenha o resultado por mês e ano.


2

para obter os valores de mês e ano da coluna de data

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


1

A lógica será:

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

O LIKEoperador selecionará todas as linhas que começam com $_POST['period']seguido pelo traço e o dia do mês

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Algumas informações adicionais


4
-1 Operações de string em dados representados internamente como um inteiro !? Está falando sério?
aefxx 01 de

@Yaroslav Sim, altamente eficiente, suponho: D
aefxx

2
Sem índice. Ele primeiro converte o valor da data em string e, em seguida, corresponde a essa string. No MySQL, qualquer tipo de coluna pode ser consultado por LIKE. Mas ainda vai funcionar: D
Yaroslav

2
O pequeno bobby dá mesa a alguém?
Rob

Não há necessidade de ficar louco por performance o tempo todo, agora você. Às vezes, o esforço e o tempo que você dedica a algo para fazê-lo funcionar alguns microssegundos mais rápido não faz nenhuma diferença, mas você perdeu esse tempo.
Hristo Petev,

0

Aqui está uma consulta que utilizo e ela retornará cada registro dentro de um período como uma soma.

Aqui está o 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();
?>

Isso lista cada emp_nr e a soma das horas mensais que eles acumularam.


0

você pode fazer isso alterando $ q para este:

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

-1

Sim, isso está funcionando, mas retorna apenas uma linha enquanto houver várias linhas para recuperar usando apenas as colunas selecionadas. Como SELECT Title, Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09 retorna apenas uma linha.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.