0

Есть таблица в db MySQL с полями (id, user_name, logs_time). Колонка logs_time имеет тип timestamp. Ко мне приходят данные из формы (месяц, который выберет клиент). Как сделать выборку по месяцам из таблицы?

Вот что получилось, но с годами работает, а с месяцами - нет(((

$Y = $_POST['year'];
$m = $_POST['month'];
$sun = $Y.$m;
$gtd = date("m", strtotime($sun));
echo $gtd;
$q = mysqli_query($link, "SELECT * FROM minicms WHERE MONTH(logs_time)=$m  /*year(logs_time) = $Y*/");
for ($c=0; $c<mysqli_num_rows($q); $c++)
{
$f = mysqli_fetch_array($q);
echo "$f[user_name] $f[logs_time] <br>";
}
  • Пользователь вводит тот месяц через форму, за который нужна выборка – Ushimitsu Jul 18 '17 at 18:09
  • https://ru.stackoverflow.com/questions/484446/%D0%94%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B7%D0%B0-%D0%BF%D1%80%D0%B5%D0%B4%D1%8B%D0%B4%D1%83%D1%89%D0%B8%D0%B9-%D0%BC%D0%B5%D1%81%D1%8F%D1%86-%D1%81-%D1%83%D1%87%D0%B5%D1%82%D0%BE%D0%BC-%D0%B3%D0%BE%D0%B4%D0%B0-%D0%BA%D0%B0%D0%BA-yearweek/484450#484450 – Mike Jul 18 '17 at 18:58
  • Да, год тоже он вводит. Получается необходимо найти все строки таблицы, где совпадают значения месяца и года сразу(т.е. в конкретном году). – Ushimitsu Jul 18 '17 at 19:46

3 Answers3

1

можно использовать date_format функцию mysql и далее таким запросом, подставляя месяц и год или отдельно месяц, если год не важен (тогда %Y из формата нужно убрать)

select * from minicms where date_format(logs_time, "%m.%Y") = "07.2017"
nnick
  • 121
  • Думаю можно и по другому, но не могу попробовать из-за ошибки: Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given (и номер строки). – Ushimitsu Jul 18 '17 at 18:45
  • @Ushimitsu https://ru.stackoverflow.com/questions/423439/mysql-fetch-array-expects-parameter-1-to-be-resource-or-mysqli-result-boole – Mike Jul 18 '17 at 18:55
0

И так! Задача состояла именно в том, что пользователь делает выборку из БД по году и месяцу, поэтому мы их записываем в переменные(т.к. многие общие операции с датами не подходят). Решение:

    $link = mysqli_connect($host, $user, $password, $dbname) or die("kyky");

$Y = $_POST['year'];
$m = $_POST['month'];
$gtd = date("m", strtotime($m)); //Изначально из формы получаем как March или 
//подобное, поэтому приводим как в базе и получится "03";
$q = mysqli_query($link, "SELECT * FROM minicms WHERE MONTH(logs_time)= $gtd and YEAR(logs_time)=$Y"); // А тут встроенные функции SQL month и year )))

//echo gettype($q);
for ($c=0; $c<mysqli_num_rows($q); $c++)
{
$f = mysqli_fetch_array($q);
echo "$f[user_name] $f[logs_time] <br>";
}

Так же переменная, в которую мы записываем массив, может оказать boolean, что означает возврат false и запрос к базе не удался(нужно проверять чуть не каждую строку в коде, в моем случае было то, что я запрашивал февраль, а записи начинаются с марта).

0

Ваше собственное решение подходит, если таблица относительно небольшая и не оптимизирована для выборки по полю logs_time, то есть поле не входит в индексы. Использование функций month, year, как, по всей вероятности, и date_format даже на типе datetime, который представляет собой просто упакованные в integer цифры из даты, не позволяет применить индексы и приведет к filesort. С timestamp, мне кажется, все так же, поскольку этим функциям с таким типом работать еще сложнее.

Информация с enSO: https://stackoverflow.com/questions/40252101/index-on-date-field-and-month-year-functions

В вашем случае, поскольку выбрать надо один месяц из одного года, лучше получить граничные значения timestamp для этих дат и использовать

where logs_time > $beginvalue and logs_time < $endvalue

Как это сделать в MySQL, примерно описано здесь: https://stackoverflow.com/questions/11133760/mysql-convert-datetime-to-unix-timestamp

Не очень удобно. Может, удобнее это сделать на PHP.

Понимаю, что ответ не полный, но, надеюсь, принесет пользу.