SQL 查询高尔夫分数排行榜

SQL Query for Golf Score Leaderboard

我正在使用 Wordpress 插件创建 SQL 报告查询 MySQL table。我不熟悉 SQL,但我想查询具有来自同一用户的多个条目的 table。我需要将用户按学生和教师分开,按用户分别汇总五个类别的总数,并为学生开发一个排行榜,为教师开发一个排行榜。领先者基于高尔夫分数,该分数是通过对五个类别中的每个类别中的用户进行排名并根据综合分数(通过添加排名)按升序排序计算得出的。

我提到的所有字段(用户、Role-Student 或教师,以及五个类别)都是 table 的名为 field_name 的列中的值,需要转向 headers。每个字段的关联值位于 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 = 类别 1, c1r=类别1排名

应该隐藏高尔夫得分、表格和角色列。

有人知道如何将其放入查询中吗?提前致谢。

我不得不将数据放入带有标识列的 table 中,并假设这些行将按顺序添加。除非有一个专栏你遗漏了,否则就没有办法做到这一点。如果您无法在其他任何地方访问 SQL 服务器,您应该可以使用 SQL Fiddle。

SQL Fiddle

MS SQL Server 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 ??