Выберите mySQL только по месяцу и году


103

У меня есть столбец в моей базе данных mySQL, в котором есть несколько строк. Одна из этих строк - это ДАТА, например:2012-02-01

Я хочу сделать SELECT с PHP только на основе года и месяца.

Логика ВЫБОРА будет следующей:

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

Конкретный месяц и год будут передаваться из $_POSTпеременной, например$_POST['period']="2012-02";

Как мне это сделать?


2
Вы можете использовать выражение BETWEEN
Бен Кэри

Ответы:


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

6
Ваш запрос не будет масштабироваться, потому что ему нужно выполнить полное сканирование таблицы, если в MySQL нет какой-либо оптимизации, о которой я не знаю.
aefxx 01

2
Это правда для EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley 01

20

Если у вас есть

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

Сначала найдите первый день месяца:

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

Затем этот запрос будет использовать индекс, Dateесли он у вас есть:

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

Можно также использовать инклюзивно-исключающие интервалы, которые работают довольно хорошо (вам не нужно беспокоиться, если столбец DATE, DATETIMEили TIMESTAMP, ни о точности:

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

Предупреждение безопасности:

Вы должны правильно экранировать эти значения или использовать подготовленные операторы. Короче говоря, используйте любой метод, рекомендованный в наши дни в PHP, чтобы избежать проблем с SQL-инъекциями.


2
Да, +1 для промежуточных значений, я изначально использовал функции Год + Месяц, но они не масштабировались и не использовали индексы.
sobelito 05

@sobelito Ага. Я обычно предпочитаю инклюзивно-эксклюзивные интервалы. Сообщение обновлено.
ypercubeᵀᴹ

Пожалуйста, избегайте этих значений или используйте заранее подготовленные операторы ... 😓
Джаред

9

Ну вот. Оставьте вычисления PHP и сохраните свою БД. Таким образом можно эффективно использовать индекс Dateстолбца.

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

ИЗМЕНИТЬ
Забыл преобразование метки времени Unix.


Он удобен для индексации, но strtotime дает вам int, и вам нужно сначала преобразовать его в date для mysql.
piotrm

Это должно быть конкатенация строк, а не операция суммы:$end = strtotime($date .' 1 month - 1 second');
Константин Переяслов


6

Предположим, у вас есть поле базы данных created_at, где вы берете значение из отметки времени. Вы хотите выполнить поиск по году и месяцу с даты created_at.

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

3

Здесь НАЙТИ запись по МЕСЯЦУ и ДАТЕ в mySQL

Вот ваше значение POST $_POST['period']="2012-02";

Просто взорвите значение тире $Period = explode('-',$_POST['period']);

Получить массив из значения разнесения:

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

Введите значение в SQL-запрос:

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

Получите результат по МЕСЯЦУ и ГОДУ.


2

чтобы получить значения месяца и года из столбца даты

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


1

Логика будет такая:

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

LIKEОператор выбирает все строки , которые начинаются с $_POST['period']последующим тиром и день Монта

http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html - Некоторая дополнительная информация


4
-1 Строковые операции с данными, внутренне представленными как целое число !? Ты серьезный?
aefxx 01

@Yaroslav Да, очень эффективен, я полагаю: D
aefxx

2
Без индекса. Сначала он преобразует значение даты в строку, а затем соответствует этой строке. В MySQL любой тип столбца может быть запрошен LIKE. Но все равно будет работать: D
Ярослав

2
Маленькие столики для бобби?
Роб

Нет необходимости постоянно сходить с ума по производительности, а теперь. Иногда усилия и время, которые вы вкладываете, чтобы заставить это работать на пару микросекунд быстрее, не имеют никакого значения, но вы потеряли это время.
Христо Петев

0

Вот запрос, который я использую, и он вернет каждую запись за период в виде суммы.

Вот код:

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

Здесь перечислены каждый emp_nr и сумма часов, которые они накопили за месяц.


0

вы можете сделать это, изменив $ q на это:

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

-1

Да, это работает, но возвращает только одну строку, в то время как есть несколько строк для извлечения, используя только выбранные столбцы. Подобно SELECT Title, Date FROM mytable WHERE YEAR (Date) = 2017 AND MONTH (Date) = 09 возвращает только одну строку.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.