Объединение трех таблиц с двумя динамическими значениями

0

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

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

  • Код товара
  • ProductName (VarChar)

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

  • PlayerID
  • PlayerName (VarChar)

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

  • GuessID
  • PlayerID
  • Код товара
  • Угадай (Инт)

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

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

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

  • 0
    «Это не имеет никакого смысла для меня.» Потому что ваш запрос не имеет смысла, потому что это не ANSI SQL. Используемые неагрегированные столбцы в предложении SELECT также должны быть в предложении GROUP BY, чтобы быть допустимым ANSi SQL. MySQL расширяет GROUP BY с помощью «функции», где это не требуется, но может привести к неверным данным.
  • 0
    .. В более современных версиях MySQL можно отключить расширенную функцию GROUP BY с помощью sql_mode с именем ONLY_FULL_GROUP_BY. Кроме того, мы советуем вам прочитать это и предоставить нам пример данных и ожидаемых результатов.
Показать ещё 1 комментарий
Теги:

3 ответа

1
Лучший ответ

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

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
    Это сделал это! Спасибо! Это имеет больше смысла, чем использование 'group by', теперь, когда у меня правильный запрос :). Еще раз спасибо!
0

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

Вы можете использовать последнее значение в этом запросе. Вы также можете использовать первое значение, заказав 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
  • 0
    Функции Windows работают только в MySQL 8.0+, если вы забыли это упомянуть.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню