2015-02-15 3 views
1

Я запрашиваю таблицу MySQL, используя плагин Wordpress. Создайте SQL-отчет. Я не знаком с SQL, но я ищу запрос в таблице, содержащей несколько записей от одних и тех же пользователей. Мне нужно отделить пользователей от студентов и учителей, объединить итоговые суммы по пяти категориям индивидуально от пользователя и разработать таблицу лидеров для студентов и одну для учителей. Лидеры основаны на оценке гольфа, которая рассчитывается путем ранжирования пользователя в каждой из пяти категорий и сортировки в порядке возрастания на основе комбинированного балла (от добавления рейтинга).SQL Query for Golf Score Leaderboard

Все поля, которые я упомянул (Пользователь, Роль-Студент или Учитель, и пять категорий), являются значениями в столбце таблицы с именем field_name и должны быть повернуты в заголовки. Значения, связанные для каждого поля находятся под FIELD_VALUE колонны, а третьи имена столбцов формы, которую она приходит из (чисел):

form_name   field_name   field_value 
numbers   user    a 
numbers   role    student 
numbers   category1   4 
numbers   category2   9 
numbers   category3   7 
numbers   category4   3 
numbers   category5   2 
numbers   user    b 
numbers   role    student 
numbers   category1   7 
numbers   category2   5 
numbers   category3   8 
numbers   category4   2 
numbers   category5   9 
numbers   user    a 
numbers   role    student 
numbers   category1   2 
numbers   category2   6 
numbers   category3   1 
numbers   category4   8 
numbers   category5   8 
numbers   user    c 
numbers   role    teacher 
numbers   category1   2 
numbers   category2   11 
numbers   category3   3 
numbers   category4   8 
numbers   category5   5 
numbers   user    d 
numbers   role    teacher 
numbers   category1   1 
numbers   category2   13 
numbers   category3   6 
numbers   category4   8 
numbers   category5   7 

Там в неустановленном количестве пользователей. Результат должен содержать имя пользователя, суммарную сумму каждой категории, рейтинг в каждой категории и окончательный ранг. Ему не нужно отображать роль (как ученика или учителя, так как я помещу таблицу лидеров учащихся на одну страницу, а учителя - на другую), имя формы или оценку гольфа (от сложения всей отдельной категории рейтинги Т.е:.

user c1 c1r c2 c2r c3 c3r c4 c4r c5 c5r golf overall form role 
a 6 2 14 1 8 1 11 1 10 1 6 1  numbers student 
b 7 1 5 2 8 1 2 2 9 2 8 2  numbers student 

Второй, но аналогичный запрос будет тянуть число учителей:

user c1 c1r c2 c2r c3 c3r c4 c4r c5 c5r golf overall form role 
d 1 2 13 1 6 1 8 1 7 1 6 1  numbers teacher  
c 2 1 11 2 3 2 8 1 5 2 8 2  numbers teacher 

c1 = category1, C1R = category1 ранг

в поле счет, форма и роль столбцы должны быть скрыты.

У кого-нибудь есть идея, как поместить это в запрос? Заранее спасибо.

+0

Можете ли вы разделить таблицу (ы) структуру (ы), пожалуйста? – Mureinik

+0

Табличные структуры добавлены к вопросу. Любой совет? Спасибо – chan

+0

Эти данные едва ли имеют какую-либо структуру, и это не типичный вопрос SQL, а тот факт, что MySQL уже ограничен во многих функциях, полезных для работы над этой проблемой. – shawnt00

ответ

0

Мне пришлось отбросить данные в таблицу с столбцом идентификации и предположить, что строки будут добавляться последовательно. Если бы не колонка, которую вы оставили, то просто невозможно ее сделать. Вы должны иметь возможность использовать SQL Fiddle, если у вас нет доступа к SQL Server в другом месте.

SQL Fiddle

сервера Настройка MS SQL 2008 схемы:

create table T (id int not null identity, nm varchar(20), val varchar(20)); 
insert into T (nm, val) values 
    ('user', 'a'), 
    ('role', 'student'), 
    ('category1', '4'), 
    ('category2', '9'), 
    ('category3', '7'), 
    ('category4', '3'), 
    ('category5', '2'), 
    ('user', 'b'), 
    ('role', 'student'), 
    ('category1', '7'), 
    ('category2', '5'), 
    ('category3', '8'), 
    ('category4', '2'), 
    ('category5', '9'), 
    ('user', 'a'), 
    ('role', 'student'), 
    ('category1', '2'), 
    ('category2', '6'), 
    ('category3', '1'), 
    ('category4', '8'), 
    ('category5', '8'), 
    ('user', 'c'), 
    ('role', 'teacher'), 
    ('category1', '2'), 
    ('category2', '11'), 
    ('category3', '3'), 
    ('category4', '8'), 
    ('category5', '5'), 
    ('user', 'd'), 
    ('role', 'teacher'), 
    ('category1', '1'), 
    ('category2', '13'), 
    ('category3', '6'), 
    ('category4', '8'), 
    ('category5', '7') 

Запрос 1:

with u0(id, name) as (
    select id, val from T where nm = 'user' 
), 
users(id, [user], [role]) as (
    select u.id, u.name, r.val 
    from u0 as u inner join T as r on r.id = u.id + 1 and r.nm = 'role' 
), 
scores([user], c1, c2, c3, c4, c5) as (
    select 
     [user], 
     sum(case when category = 'category1' then score end), 
     sum(case when category = 'category2' then score end), 
     sum(case when category = 'category3' then score end), 
     sum(case when category = 'category4' then score end), 
     sum(case when category = 'category5' then score end) 
    from (
     select 
      nm as category, cast(val as int) as score, 
      (
       select [user] from users where id = (
        select max(u.id) from u0 as u where u.id < s.id 
       ) 
      ) as [user] 
     from T as s 
     where nm like 'category_' 
     ) as s_pivot 
    group by [user] 
) 
select 
    u.[role], u.[user], 
    c1, rank() over (partition by u.[role] order by c1 desc) as c1r, 
    c2, rank() over (partition by u.[role] order by c2 desc) as c2r, 
    c3, rank() over (partition by u.[role] order by c3 desc) as c3r, 
    c4, rank() over (partition by u.[role] order by c4 desc) as c4r, 
    c5, rank() over (partition by u.[role] order by c5 desc) as c5r, 
    rank() over (partition by u.[role] order by c1+c2+c3+c4+c5 desc) as overall 
from 
    (select distinct [user], [role] from users) as u 
    inner join scores as s on s.[user] = u.[user] 
order by 
    u.[role], u.[user] 

Results:

| ROLE | USER | C1 | C1R | C2 | C2R | C3 | C3R | C4 | C4R | C5 | C5R | OVERALL | 
|---------|------|----|-----|----|-----|----|-----|----|-----|----|-----|---------| 
| student | a | 6 | 2 | 15 | 1 | 8 | 1 | 11 | 1 | 10 | 1 |  1 | 
| student | b | 7 | 1 | 5 | 2 | 8 | 1 | 2 | 2 | 9 | 2 |  2 | 
| teacher | c | 2 | 1 | 11 | 2 | 3 | 2 | 8 | 1 | 5 | 2 |  2 | 
| teacher | d | 1 | 2 | 13 | 1 | 6 | 1 | 8 | 1 | 7 | 1 |  1 | 

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

select 'insert into T (nm, val) values (''' + field_name + ''', ''' + field_value + ''')' 
from ?? 
+0

Это очень полезно, спасибо. Я получаю ошибку в первой строке с u0.В моей таблице нет обычного столбца Auto Incr id, у него есть столбец submit_time с секундами, выходящими из 4 десятичных знаков, действующих как первичный ключ. Я попытался добавить идентификатор, но не могу заставить его подключаться ко всем связанным полям в поле_имя, как это делает submit_time. Поэтому я заменил submit_time на id в вашем решении. Это вызывает ошибку u0? – chan

+0

Замена может работать, но вы по-прежнему не сможете использовать мою версию MySQL, которая не поддерживает CTE (WITH) или даже функцию рангов. Я не говорю, что это невозможно, но я не был готов принять этот вызов, поскольку мои знания в отношении особенностей MySQL довольно ограничены. – shawnt00

+0

На самом деле, если вы заменили submit_time на _every_ появление id, то это может (вероятно, возникло бы) вызвать проблемы. Я думаю, что только один внутри запроса u0 должен быть изменен на 'select submit_time, val ...' – shawnt00