За последние 24 часа нас посетили 22870 программистов и 1265 роботов. Сейчас ищут 770 программистов ...

Как найти минимальное значение из ограниченной выборки

Тема в разделе "PHP и базы данных", создана пользователем Vladd55, 20 мар 2023.

  1. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Добрый вечер!

    Имеется вот такой запрос:
    Код (Text):
    1. $query = mysqli_query($db, "SELECT MIN(`time`) AS `min` FROM `notice`
    2. WHERE `user_id` = '$user_id' ORDER BY `time` DESC LIMIT 5");
    3. $row = mysqli_fetch_assoc($query);
    4. $time_min = $row['min'];
    Здесь я хотел для пользователя user_id отсортировать выборку по time по убыванию и из первых пяти строк найти минимальное значение time.

    Но запрос игнорирует LIMIT 5 и выдает минимальное значение из всех записей для этого user_id.

    Ради любопытства я заменил DESC на ASC, а результат тот же.

    Как решить эту проблему?
     
  2. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Ты можешь делать запрос не по таблице, а по подзапросу, который будет ограничен limit.
    Код (Text):
    1. SELECT MIN(...)
    2. FROM (
    3.   SELECT ...
    4.   ORDER BY ...
    5.   LIMIT 5
    6. ) AS last_five
     
  3. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Попытался, но не получилось почему-то.

    Код (Text):
    1.         $query = mysqli_query($db, "SELECT MIN(`time`) FROM
    2. (`notice` WHERE `user_id` = '$user_id' ORDER BY `time` DESC LIMIT 5) AS `min`");
    3.         $row = mysqli_fetch_assoc($query);
    4.         $time_min = $row['min'];
    Выводит ошибку:

    PHP Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in …

    Сообщение относится к строке $row = mysqli_fetch_assoc($query);
     
  4. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.792
    Симпатии:
    650
    Нужно проверять результаты всех запросов, даже если они синтаксически верны!

    У вас походу синт. ошибка ;)
     
  5. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    MIN выводит только 1 значение, даже если в таблице их несколько одинаковых, потому сколько у вас там в лимит и нисходящий порядок или восходящий все равно
     
  6. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    Если нужно показать 5 записей с мин временем и отдельно показать мин значение, я бы сделал что-то вроде такого:
    Код (Text):
    1. "SELECT `time` FROM `notice` WHERE `user_id` = '$user_id' ORDER BY `time` ASC LIMIT 5"
    Потом средствами php нашел мин значение и показал все это пользователю.
    А то не очень понятно как вы хотите сделать 1 запрос таким образом, чтобы он одновременно выводил и 5 строк и 1 мин значение. Теоретически можно приделать ко всем строкам поле, где везде будет это минимальное значение, но оно нужно?
     
  7. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Подзапрос собирает 5 строк, а запрос из них выбирает минимальное значение.

    Если это за пределами возможности mysql, то с помощью РНР я могу это сделать. Но, вроде как, модератор написал, что это возможно... Вот я и пытаюсь. Пока безуспешно.
     
  8. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    В подзапросе вы пропустили SELECT и FROM. Но вы ведь понимаете, что в итоге MIN вам даст 1 значение, а даже не 1 строку?
     
  9. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Так мне и нужно одно значение, я его и ищу.

    В PHPMyAdmin попробовал вот такой запрос, подставив в него вместо переменных их численное значение:
    Код (Text):
    1. SELECT MIN(`time`) AS `min` FROM `notice` (SELECT `time` FROM `notice` WHERE `user_id` = 72 ORDER BY `time` DESC LIMIT 5)
    Пишет Ошибка в запросе.
     
  10. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    Тогда чем вас не устраивает:
    Код (Text):
    1. "SELECT MIN(`time`) FROM `notice` WHERE `user_id` = '$user_id'
    Или
    Код (Text):
    1. "SELECT `time` FROM `notice` WHERE `user_id` = '$user_id' ORDER BY `time` ASC LIMIT 1"
    Или вам важен подзапрос?
     
  11. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Один из `notice` - лишний
     
  12. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Как я уже писал в теме, я хотел для пользователя user_id отсортировать выборку по time по убыванию и из первых пяти строк найти минимальное значение time.

    Ваши варианты эту задачу не решают.
     
  13. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    А все понял, вы хотели из 5 наибольших значений выбрать 1 наименьшее. Держите ваш запрос с подзапросом:
    Код (Text):
    1. SELECT MIN(`time`)
    2. FROM (
    3.     SELECT `time` FROM `notice` WHERE `user_id` = 72
    4.     ORDER BY `time` DESC
    5.     LIMIT 5
    6. )  AS `min`
    Сори, невнимательно прочел.
     
    Vladd55 нравится это.
  14. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Тогда так:
    Код (Text):
    1. SELECT MIN(`time`) AS `min` FROM  (SELECT `time` FROM `notice` WHERE `user_id` = 72 ORDER BY `time` DESC LIMIT 5)
    Ответ MySQL: [​IMG]

    #1248 - Every derived table must have its own alias
     
  15. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Псевдоним в конце добавить надо
    Как в #13.
     
  16. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Супер! Большое спасибо!
    А то я уже не надеялся...
     
  17. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Радость моя была преждевременной...

    В PHPMyAdmin запрос исполняется и показывает нужный результат в
    Параметры
    MIN(time)
    1679389366

    А в скрипте результат не виден.
    Код (Text):
    1. $query = mysqli_query($db, "SELECT MIN(`time`) FROM
    2. (SELECT `time` FROM `notice` WHERE `user_id` = '72'
    3. ORDER BY `time` DESC LIMIT 5)  AS `min`");
    4. $row = mysqli_fetch_assoc($query);
    5. $time_min = $row['min'];
    Диагностика: PHP Notice: Undefined index: min в строке $time_min = $row['min'].
     
  18. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Можно поставить AS `min` дважды:

    Код (Text):
    1. $query = mysqli_query($db, "SELECT MIN(`time`) AS `min` FROM
    2. (SELECT `time` FROM `notice` WHERE `user_id` = '72'
    3. ORDER BY `time` DESC LIMIT 5)  AS `min`");
    4. $row = mysqli_fetch_assoc($query);
    5. $time_min = $row['min'];
    Так работает. Но это какое-то извращение.
    Нет ли корректного работоспособного решения?
     
  19. Aleksandr.B

    Aleksandr.B Новичок

    С нами с:
    2 фев 2023
    Сообщения:
    152
    Симпатии:
    40
    Адрес:
    Барнаул
    Код (Text):
    1. $query = mysqli_query($db, "SELECT MIN(`time`) FROM
    2. (SELECT `time` FROM `notice` WHERE `user_id` = '72'
    3. ORDER BY `time` DESC LIMIT 5)  AS `min`");
    4. $row = mysqli_fetch_assoc($query);
    5. $time_min = current($row);
     
  20. dantemgs

    dantemgs Новичок

    С нами с:
    24 дек 2022
    Сообщения:
    47
    Симпатии:
    9
    Если внимательно посмотрите, то у вас в админке не `min`, а `MIN(time)`.
    Можно псевдоним внутреннего подзапроса назвать иначе, например `temp`. Внешний запрос использует псевдоним `temp` для ссылки на результат подзапроса.
     
  21. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Здесь непарные скобки.
     
  22. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Какая задача, такое и решение. ;) SQL нормальный. Попробуй сформулировать свою хотелку на русском так, чтобы она была логична и понятна. А то ты начал с описания КАК ты собираешся реализовать, а не ЧТО ты хочешь сделать.
    --- Добавлено ---
    да он чемпион по невнимательности! :)
     
  23. Vladd55

    Vladd55 Новичок

    С нами с:
    11 дек 2021
    Сообщения:
    84
    Симпатии:
    1
    Как я уже писал в теме, я хотел для пользователя user_id отсортировать выборку по time по убыванию и из первых пяти строк найти минимальное значение time.

    Проблема решена, спасибо всем ответившим!
     
    #23 Vladd55, 21 мар 2023
    Последнее редактирование: 21 мар 2023
  24. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    Ну вот опять.