MySQL select с MIN () не выделяет все строки - PullRequest
0 голосов
/ 26 ноября 2018

Справочная информация: Я программист-хобби, пытаюсь создать личную таблицу лидеров для гоночной игры.Это сделано с Raspberry Pi, управляющим MariaDB.Лидерборд соскоблен с другого сайта и хранится в БД.Затем мои персональные времена получаются из игры по протоколу UDP и сохраняются в той же MariaDB на Pi.Результаты показаны на странице php.Пользователь может выбрать другой автомобиль и отслеживать комбо на странице php.Я хочу показать каждому игроку лучшее (минимальное) время прохождения круга для выбранной автомобильной комбо-трек.(Имена игроков являются официальными тегами игрока, где дубликаты не допускаются. Все они уникальны.)

С таким оператором SELECT я получаю 84 строки, но я получаю все свои собственные временные промежутки и хочу толькопокажи мое лучшее время прохождения для этой автомобильной трассы.

$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";

Я пытался использовать SELECT, как это, но тогда я получил только 54 строки?У меня записано только два круга, поэтому куча кругов от других людей не отображается.

$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes 
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' 
ORDER BY laptime ASC";

Я тоже пробовал разные SELECT, например, с LEFT JOIN.$ Trackselect и $ carselect - это значения из выпадающих списков на странице php. Похоже, они работают в обоих случаях.Значение $ choice от двух разных кнопок на странице php.Кнопка 1 устанавливает $ choice = "".Кнопка 2 устанавливает $ choice = "AND player LIKE 'Maskmagog'".Это используется, чтобы показать только мои часы.Кажется, он работает.

Вопрос: Почему некоторые строки не выбираются во втором SELECT?

Вот первые 5 выводов для первого SELECT:

1.  sel                 Ginetta G40 Junior  00:56.017   
2.  {DFRUK}michaeldimel Ginetta G40 Junior  00:56.149   
3.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
4.  piquet              Ginetta G40 Junior  00:56.756   
5.  Oomph               Ginetta G40 Junior  00:56.981   

и 2-й ВЫБОР:

1.  Yorkshire Farmer    Ginetta G40 Junior  00:56.709   
2.  saya777             Ginetta G40 Junior  00:57.002   
3.  Lamb4chop™          Ginetta G40 Junior  00:57.067   
4.  Jonge               Ginetta G40 Junior  00:57.250   
5.  NsGTR35             Ginetta G40 Junior  00:57.296   

Как видите, выживает только "Йоркширский фермер" и отображается в обоих выборках, и я не понимаю, почему.

Вот полная страница php на Pastebin: https://pastebin.com/ALTzfm2S

РЕДАКТИРОВАТЬ: Благодаря комментариям ниже, я наконец понимаю почему 2-й SELECT не делает 'т работа.Сначала он выбирает игроков наименьшее время прохождения круга, независимо от трассы / машины.Затем применяется WHERE, и игроки, у которых наименьшее время круга установлено на других машинах / трассах, конечно же, удаляются из результата.D'о!:)

РЕДАКТИРОВАТЬ 2: Ну, кажется, я не могу отметить более одного ответа.Похоже, что оба решения работают, большое спасибо всем участникам!Я не могу сказать, является ли один ответ лучше / более полезным / более правильным.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Исходя из ваших требований, вам не нужны вложенные SELECT.Вы можете добавить условия к своему внутреннему запросу и использовать их:

SELECT player, MIN(laptime) AS min_laptime
FROM laptimes 
WHERE track = ?
    AND carname LIKE ?
    AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC

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

0 голосов
/ 26 ноября 2018

Ваша проблема в том, что ваш подзапрос возвращает минимальное время круга для игрока независимо от трассы или автомобиля .Вам нужно вернуть минимальное время круга игрока для каждой машины на каждой гоночной трассе, поэтому вам нужно изменить GROUP BY на

GROUP BY player, track, carname

, а затем вам также нужно добавить track и carname для подзапроса SELECT и JOIN.Поэтому ваш запрос должен выглядеть так:

$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes 
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' 
ORDER BY laptime ASC";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...