Объединение трех таблиц с двумя динамическими значениями - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь создать базу данных для угадайки, где игрок должен угадать ценность того или иного продукта. У меня три стола;

Одна таблица для продуктов со следующими столбцами:

  • ProductID
  • ProductName (VarChar)

Один стол для игроков со следующими столбцами

  • PlayerID
  • PlayerName (VarChar)

Один стол, где хранятся игроки, продукты и их догадки, т.е.

  • GuessID
  • PlayerID
  • ProductID
  • Угадай (Int)

Я пытаюсь найти способ объединить, какой игрок (PlayerName), который сделал наибольшее предположение (Угадай) для КАЖДОГО продукта (ProductName), то есть способ суммировать каждый отдельный продукт, наибольшее предположение для каждого продукта и имя оч игрока, который сделал предположение.

Пока мне удалось получить только правильное 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 выбран для запроса, указанного выше. Это не имеет никакого смысла для меня.

Буду признателен, если кто-нибудь из вас, ребята, укажет мне правильное направление.

Приветствия.

Ответы [ 3 ]

0 голосов
/ 05 января 2019

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

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)
0 голосов
/ 05 января 2019

Один из способов - использовать что-то вроде взлома в 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+.

0 голосов
/ 05 января 2019

Вы можете использовать последнее значение в этом запросе. Вы также можете использовать первое значение, заказав 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...