|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Привет всем! Название темы умнее не придумал, т.к. в двух словах не опишешь :( В общем, ситуация следующая. Есть простая таблица игроков, нас интересуют только поля "id" и "level". Нужно получить N (например, 10) любых игроков, "id" которых должен быть в заданном списке, а уровень (level) находится в определённом диапазоне, причём уровень не должен повторяться. Что-то вроде этого (константы для примера, у меня это переменные из PHP): Код: sql 1.
Здесь всё ОК, но вот потом, если запрос вернёт менее 10 игроков (например, нашёл 4), оставшиеся 6 надо "добить" игроками из базы по тем же условиям, но уже без проверки ID, типа того: Код: sql 1.
То есть те, перечисленные, игроки находятся как бы в приоритете :) Попробовал сделать двумя запросами и в PHP их объединить в один массив, но тут мешают две проблемы - во-первых, второй запрос может выдать частично тех же людей, что и первый, но это не так страшно, есть варианты решения. А вот сделать, чтобы второй запрос не повторял значений level из первого - это уже сложнее :( Либо вместо BETWEEN делать перечисление "свободных" уровней, либо делать лимит в 2 раза больше (чем нужно) а потом в PHP отсеивать лишних... Вопрос - нельзя ли вообще всё это как-нибудь организовать в одном сложном запросе? :) Заранее спасибо :) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2019, 00:05 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Egis, что делать в ситуации, если в таблице в принципе не набирается достаточного количества игроков с уникальными уровнями? К примеру, все игроки имеют одинаковый уровень. Или уровень ни одного из игроков не попадает в заданный диапазон уровней. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2019, 05:41 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Щукина Анна, Просто вернуть тех, которые нашлись (или ничего), в общем то что и делает запрос при указании LIMIT ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2019, 13:41 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Видимо, проще не получится, ну что ж... А еще такой вопрос: допустим, мне надо получить по одному игроку каждого уровня, скажем от 1 до 20 (если на каком-то уровне ни одного игрока нет - ничего страшного) - каким образом ЭФФЕКТИВНЕЕ это сделать? Простейший (и, возможно, наилучший) вариант, для примера: Код: plsql 1.
Есть ли, например, смысл обозначать лимит в 20 человек, или GROUP и так прекращает поиск, если 20 человек найдено? "Случайность" выборки не имеет значения, т.е. нужен любой первый попавшийся игрок с нужным уровнем. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.07.2019, 00:00 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Уточните версию MySQL. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.07.2019, 07:09 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Сервер: MySQL (Localhost via UNIX socket) Версия сервера: 5.5.41-0+wheezy1 Версия протокола: 10 MySQL-кодировка: UTF-8 Unicode (utf8) Apache/2.2.22 (Debian) Версия MySQL-клиента: 5.5.41 PHP расширение: mysqli ... |
|||
:
Нравится:
Не нравится:
|
|||
16.07.2019, 13:12 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Ну если в принципе всё равно какой id для каждого level вернётся, то максимальный (или там минимальный) подойдёт? Тогда я бы сделал так: Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.07.2019, 14:25 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Ну, или коли уж версия 5.5 и чхать хотела на неполную группировку, MAX() убрать, и фиг с им, с несоответствием стандарту: Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.07.2019, 14:27 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Спасибо за ответ! Я только не очень понял, что делает строчка Код: sql 1.
Если это ответ на первый вопрос (т.е. моя мечта искать в одном запросе сначала среди "приоритетных" ID, и если нужных уровней среди них нет то дополнить любыми с нужным уровнем), то у меня это не работает - всё равно возвращаются те же самые, не приоритетные случайные ID. Если указать MAX, то возвращаются другие, крупные (максимальные) id для тех же уровней, но указанные в списке никак не участвуют (разве что, попадаются случайно). Т.е. ORDER BY у меня вроде как ничего не меняет (только почему-то меняет порядок записей на хаотичный, но порядок записей не имеет для меня значения). Пример без ORDER BY: Код: sql 1. 2. 3. 4. 5.
Возвращает: |1169123|1 |934302|2 |3484|3 |93331|4 |788599|5 |1630225|6 |996868|7 |405900|8 |260797|9 |568414|10 Пример с ORDER ID (перечислены реальные ID, их level точно входят в нужный диапазон): Код: sql 1. 2. 3. 4. 5. 6.
|3484|3 |93331|4 |260797|9 |405900|8 |568414|10 |788599|5 |934302|2 |996868|7 |1169123|1 |1630225|6 ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 01:13 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Не нашёл как редактировать сообщение... Когда пробовал последний раз забыл DESC, но это никак не повлияло на результат. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 01:18 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
EgisЯ только не очень понял, что делает строчка Код: sql 1.
Если это ответ на первый вопрос (т.е. моя мечта искать в одном запросе сначала среди "приоритетных" ID, и если нужных уровней среди них нет то дополнить любыми с нужным уровнем), то у меня это не работает Попробуйте такой вариант: Код: sql 1.
EgisНе нашёл как редактировать сообщение...И не найдете, нет такого функционала для пользователей. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 02:47 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
[quot vkle] Попробуйте такой вариант: Код: sql 1.
Увы, точно такой же результат как для "ORDER BY id IN" :( Всегда выбирает минимальный ID из ВСЕХ с подходящим уровнем. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 03:41 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Если пишу вот так: Код: sql 1. 2. 3. 4. 5.
то f всегда 0, и результат прежний. Если убрать GROUP BY level, то первые 5 значений берутся из "приоритетных", и f = 5,4,3,2,1. Но, соответственно, вылезают все записи с повторяющимися уровнями :( id - первичный уникальный ключ типа BIGINT, если что, мало ли... ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 04:02 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
EgisЯ только не очень понял, что делает строчка Код: sql 1.
Это, судя по первым двум словам, ORDER BY Clause. Т.е. предложение сортировки. Сортировка выполняется по результату вычисления указанного выражения, причём по причине наличия DESC - в порядке убывания. Оператор IN возвращает TRUE, если условие истинно (искомое значение присутствует в списке), иначе FALSE. TRUE - это алиас целочисленного значения 1, FALSE - алиас целочисленного значения 0. Т.е. фактически при сортировке сначала будут выведены записи со значением 1 (TRUE) - т.е. те, чьи id присутствуют в списке, а затем остальные (которых в списке нет). ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 07:21 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Akina, Спасибо за разъяснения. Всё работает как вы говорите, но, к сожалению для моего случая, уже только после процедуры группировки по уровню (как я понял) :( С FIELD аналогично, если не делать группировку то всё было бы прекрасно... ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 13:53 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Egisдля моего случая, уже только после процедуры группировки по уровнюПрочитал три раза, ни разу не понял... ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 15:11 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Если написать GROUP BY level, то сначала, как я понимаю, происходит сама группировка по level (уровню), и только потом ORDER BY. Грубо говоря, сортировать после группировки уже нечего, возвращаются первые попавшиеся id с нужным level, ORDER BY уже не срабатывает, т.к. после группировки уже не остается "приоритетных" ID ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 15:38 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
Egis, Подозреваю, что тупое решение "в лоб" тут будет и достаточно простым. Два запроса из первого поста соединить UNION и третим SELECT по результату объединения сделать итоговую десятку и сортировку. Вроде бы, UNION сохраняет порядок записей из вложенных запросов, но если будет проблема с гарантированным получением в итоговом третьем запросе записей "обязательной" десятки, то, вероятно, в оба вложенных запроса придется добавить по одному полю с фиксированным значением, а в итоговом сделать по нему первый уровень сортировки. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.07.2019, 19:55 |
|
Помогите составить сложный запрос
|
|||
---|---|---|---|
#18+
EgisГрубо говоря, сортировать после группировки уже нечего, возвращаются первые попавшиеся id с нужным level, ORDER BY уже не срабатывает, т.к. после группировки уже не остается "приоритетных" IDА что Вы хотите? изначально поставлена задача, гарантированно получающая недетерминированный результат. Именно он и получается - жаловаться не на что, сам попросил. Меняй условия задачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.07.2019, 07:30 |
|
|
start [/forum/topic.php?fid=47&fpage=33&tid=1829051]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
34ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
2ms |
others: | 284ms |
total: | 426ms |
0 / 0 |