Виберіть mySQL лише на основі місяця та року


102

У моєму БД mySQL є стовпець, який містить ряд рядків. Один з цього ряду - ДАТА, наприклад:2012-02-01

Те, що я хочу досягти, - це зробити SELECT з PHP на основі лише року та місяця.

Логіка SELECT буде такою:

$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

5
Ваш запит не буде масштабуватися, тому що йому потрібно виконати повне сканування таблиці, якщо не буде певної оптимізації в MySQL, про яку я не знаю.
aefxx

2
Це правда EXTRACT(YEAR_MONTH FROM Date)?
cmbuckley

19

Якщо у вас є

$_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

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

EDIT
Забув перетворення часових позначок Unix.


Це зручно для індексу, але strtotime дає вам int, і вам потрібно спочатку перетворити його на дату для mysql.
піотрм

Це має бути строкове конкатенація, а не сума операції:$end = strtotime($date .' 1 month - 1 second');
Костянтин Переяслов


6

Припустимо, у вас створено поле бази даних__Так, де ви берете значення з часової позначки. Ви хочете здійснити пошук за роком та місяцем із дати створення_матеріалу.

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

3

Тут ЗНАЙДУЙТЕ запис по МЕСЯЦІ та ДАТІ в mySQL

Ось ваше значення POST $_POST['period']="2012-02";

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

Отримати масив із значення eksplode:

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/uk/pattern-matching.html - Деякі додаткові відомості


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

@Ярослав Так, високоефективний, я думаю: 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

Так, це працює, але він повертає лише один рядок, поки є кілька рядків для отримання, використовуючи лише вибрані стовпці. Як і ВИБІР ВИМОКУ, дата ВІД мібльоту, КОГО РОКУ (Дата) = 2017 І МІСЯЦЬ (Дата) = 09 повертає лише один рядок.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.