#mysql #multiple-choice
#mysql #множественный выбор
Вопрос:
У меня есть приложение с множественным выбором элементов, опций, ответов и пользовательских таблиц:
- Элемент — это, по сути, вопрос. Каждый элемент относится к одной из трех категорий. Категория хранится в виде строки в
category
поле. - С каждым элементом связано несколько параметров. У каждого параметра есть
item_id
иpoints
поля. - Всякий раз, когда пользователь выбирает вариант, создается ответ. В нем есть
user_id
,item_ id
иoption_id
поля. На пару элемент / пользователь дается ровно один ответ.
Что мне нужно
Я хотел бы иметь запрос, который суммирует результаты для каждого пользователя, по одному пользователю в строке. Каждая строка должна содержать три столбца, содержащие сумму баллов, набранных пользователем в этой категории:
Name | Points in Cat1 | Points in Cat2 | Points in Cat3
John | 3 | 1.5 | 2
Jane | 2 | 2 | 1.5
Что у меня есть
Я могу выводить точки, сгруппированные по пользователю и категории в отдельных строках:
SELECT
u.id,
u.first_name,
i.category,
sum(o.points)
FROM
answers a,
options o,
items i,
users u
WHERE a.user_id = u.id
AND a.option_id = o.id
AND o.item_id = a.item_id
AND i.id = a.item_id
GROUP BY u.id, i.category;
# Output:
# John Cat1 3
# John Cat2 1.5
# John Cat3 2
# Jane Cat1 2
# etc.
Мне нужна помощь в изменении запроса во втором списке кода таким образом, чтобы получить те же данные, но в формате, который я набросал в первом списке.
Комментарии:
1. Вместо ответа, приведенного ниже, серьезно рассмотрите проблемы отображения данных в коде приложения.
2. Спасибо! На самом деле это именно то, что я собираюсь сделать, когда проведу рефакторинг приложения и интегрирую его с другим. Просто в atm вообще нет серверной части, и я не хочу тратить много времени на эту версию.
Ответ №1:
используйте условную агрегацию с регистром, когда выражение
select firstname,
max(case when category='Cat1' then p end) "Points in Cat1"
max(case when category='Cat2' then p end) "Points in Cat2",
max(case when category='Cat3' then p end) "Points in Cat3"
from
(
SELECT
u.id,
u.first_name,
i.category,
sum(o.points) as p
FROM
answers a join users u on a.user_id = u.id join options o on a.option_id = o.id
join items i on i.id = a.item_id
GROUP BY u.id, i.category, u.id,u.first_name
)AA group by firstname
Комментарии:
1. Спасибо, это как раз то, что мне было нужно. Однако есть опечатка: «firstname» должно быть «first_name», и я использовал «group by id» вместо «group by firstname», потому что имена могут быть не уникальными.