Я пытаюсь создать базу данных для угадайки, где игрок должен угадать ценность того или иного продукта. У меня три стола;
Одна таблица для продуктов со следующими столбцами:
Один стол для игроков со следующими колонками
Одна таблица, где хранятся игроки, продукты и их догадки, т.е.
Я пытаюсь найти способ объединить, какой игрок (PlayerName), который сделал наибольшее предположение (Угадай) для каждого продукта (ProductName), то есть способ суммировать каждый отдельный продукт, самое высокое предположение для каждого продукта и имя OCH игрок, который сделал предположение.
До сих пор я смог получить только правильное ProductName и правильное значение Guess для каждого продукта. Как-то это не работает для PlayerName, и я каждый раз получаю неправильное имя.
SELECT pl.PlayerName, MAX(g.Guess), p.ProductName
FROM
guess g
INNER JOIN player pl on g.PlayerID = pl.PlayerID
INNER JOIN product p on g.ProductID = p.ProductID
GROUP BY g.ProductID;
Я предполагаю, что моя проблема в том, что каждая строка, связанная с конкретным продуктом, содержит два динамических значения; Угадай и PlayerID, который доставляет мне проблемы всякий раз, когда я пытаюсь сортировать по Максу (Угадай). Я не могу понять, какой PlayerID выбран для запроса, указанного выше. Это не имеет никакого смысла для меня.
Я был бы признателен, если бы кто-нибудь из вас, ребята, указал мне правильное направление.
Приветствия.
Используйте коррелированный подзапрос, чтобы выбрать наибольшее предположение для каждого продукта, затем выберите связанных игроков и записи продуктов во внешнем запросе, например:
SELECT
p.productname, u.playername, g.guess as "max guess"
FROM
guess_table g
INNER JOIN product_table p ON p.productid = g.productid
INNER JOIN players_table u on u.playerid = g.playerid
WHERE g.guess = (SELECT MAX(guess) FROM guess_table WHERE productid = p.productid)
Один из способов - использовать что-то вроде хака в MySQL:
SELECT SUBSTRING_INDEX(GROUP_CONCAT(pl.PlayerName ORDER BY g.guess DESC), ',', 1) as PlayerName,
MAX(g.Guess), p.ProductName
FROM guess g JOIN
player pl
ON g.PlayerID = pl.PlayerID JOIN
product p
ON g.ProductID = p.ProductID
GROUP BY p.ProductName;
Этот метод определенно имеет ограничения. Внутреннее строковое представление для GROUP_CONCAT()
ограничено примерно 1000 символами (хотя это может быть расширено). Выше предполагается, что имена не содержат запятых (хотя могут использоваться другие разделители).
Лучшее решение - использовать оконные функции, но они доступны только в MySQL 8+.
Вы можете использовать последнее значение в этом запросе. Вы также можете использовать первое значение, заказав desc (необязательно указывать неограниченный предшествующий и последующий. Кроме того, это основано на предположении, что догадка уникальна в названии продукта, так что порядок будет согласованным.
Примерные данные и результаты помогли бы увидеть, ожидается ли это или нет, но я думаю, что он будет работать здесь на основе того, что вы упомянули.
SELECT distinct p.ProductName,
last_value(Guess) over (partition by p.ProductName order by Guess rows between
unbounded preceding and unbounded following ) GuessNumber,
last_value(pl.PlayerName) over (partition by p.ProductName order by Guess rows
between unbounded preceding and unbounded following ) PlayerName
FROM guess g
inner join player pl on g.PlayerID = pl.PlayerID
inner join product p on g.ProductID = p.ProductID