重新组合所有结果 select 一会儿

regrouping all results in a select with a while

我正在做一些请求来帮助游戏开发者平衡他的游戏,我想看看有多少玩家使用什么运行e,以及平均水平

这是我的代码:

declare @runeID varchar(100)
set @runeID=22001

select counT(i.characterid) as 'user level 1 to 10', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>0 and level<11 and attached>0
select counT(i.characterid) as 'user level 11 to 20', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>10 and level<21 and attached>0
select counT(i.characterid) as 'user level 21 to 30', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>20 and level<31 and attached>0
select counT(i.characterid) as 'user level 31 to 40', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>30 and level<41 and attached>0
select counT(i.characterid) as 'user level 41 to 50', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>40 and level<51 and attached>0
select counT(i.characterid) as 'user level 51 to 60', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>50 and level<61 and attached>0
select counT(i.characterid) as 'user level 61 to 70', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>60 and level<71 and attached>0
select counT(i.characterid) as 'user level 71 to 80', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>70 and level<81 and attached>0
select counT(i.characterid) as 'user level 81 to 90', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>80 and level<91 and attached>0
select counT(i.characterid) as 'user level 91 to 100', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>90 and level<101 and attached>0
select counT(i.characterid) as 'user level 101 to 110', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>100 and level<111 and attached>0
select counT(i.characterid) as 'user level 111 to 120', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>110 and level<121 and attached>0
select counT(i.characterid) as 'user level 121 to 130', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>120 and level<131 and attached>0
select counT(i.characterid) as 'user level 131+', avg(i.maxUpgrade) as 'average level' from items i inner join characters c on i.characterId=c.characterId 
        where itemId=@runeID and level>130 and attached>0

这段代码让我在我的变量中每 10 个级别使用 运行e i select。 我从帮助我的其他人 (Gordon Linoff) 那里得到了这段代码:

select floor(level / 10) * 10 as range_start,
avg(i.maxUpgrade) as avg_level,
count(i.characterId) as number_of_user
from items i inner join
characters c
on i.characterId = c.characterId
where attached > 0
group by floor(level / 10) * 10
order by range_start ASC

此代码缩短了我所做的工作,我想知道是否可以使用 while 为我之前放入列表中的每个 运行eId 创建新列(12001,12002,12002,等等...),所以我可以得到类似的东西:

              22001_use   22001_avg_lvl    22002_use    22002_avg_lvl
level_1-9               
level_10-19             
level_20-29             
                        

所以在第一列中是等级范围的指标,第二和第三列是根据第一列玩 运行e 每 10 个等级的玩家数量,人们使用的平均等级 运行e,列表中的每个 运行e 创建 2 个新列供使用和平均水平

所以如果我或开发人员需要最新的统计数据,他只需要 运行 查询,复制结果并将其传递到 google sheet,如果他决定添加更多 运行es,也会与列表一起更新代码

我想你想要条件聚合:

select 
    floor(level / 10) * 10 as range_start,
    sum(case when i.itemid = 22001 then 1 else 0 end) as use_22001
    avg(case when i.itemid = 22001 then i.maxUpgrade end) as avg_lvl_22001,
    sum(case when i.itemid = 22002 then 1 else 0 end) as use_22002
    avg(case when i.itemid = 22002 then i.maxUpgrade end) as avg_lvl_22002
from items i 
inner join characters c on i.characterId = c.characterId
where attached > 0 and i.item_id in (22001, 22002)
group by floor(level / 10) * 10
sort by range_start ASC

这是重构代码的尝试。由于 'level' 是一个整数(来自字符 table),因此无需使用 FLOOR。消除它并删除对 CROSS APPLY'ed 虚拟 table 和列 'lvl.lvl' 的计算。然后由于某种原因在代码中有一个 'sort by' 而它应该是 ORDER BY。此外,还缺少一些逗号。像这样。

select lvl.lvl as range_start,
       sum(case when i.itemid = 22001 then 1 else 0 end) as use_22001, avg(case when i.itemid = 22001 then i.maxUpgrade end) as avg_lvl_22001,
       sum(case when i.itemid = 22002 then 1 else 0 end) as use_22002, avg(case when i.itemid = 22002 then i.maxUpgrade end) as avg_lvl_22002,
       avg(i.maxUpgrade) as tot_avg_level,
       count(i.characterId) as tot_num_users
from items i 
     join characters c on i.characterId = c.characterId
     cross apply (select (c.[level]/10)*10 lvl) lvl
where attached > 0
group by lvl.lvl
order by lvl.lvl;

要动态构建 SQL,以便它为项目 table 中的每个符文(由 itemid 表示)创建 2 列,类似这样

declare
  @select         nvarchar(max)=N'select lvl.lvl as range_start, ',
  @str1           nvarchar(max)=N' sum(case when i.itemid = ',
  @str2           nvarchar(max)=N' then 1 else 0 end) as use_',
  @str3           nvarchar(max)=N', avg(case when i.itemid = ',
  @str4           nvarchar(max)=N' then i.maxUpgrade end) as avg_lvl_',
  @str5           nvarchar(max)=N',',
  @from           nvarchar(max)=N' avg(i.maxUpgrade) as tot_avg_level,
                                   count(i.characterId) as tot_num_users
                            from items i 
                                    join characters c on i.characterId = c.characterId
                                    cross apply (select (c.[level]/10)*10 lvl) lvl
                            where attached > 0
                            group by lvl.lvl
                            order by lvl.lvl;',
  @sql            nvarchar(max);

select @sql=concat(@select,
                   string_agg(concat(@str1, cast(itemid as char(5)), 
                                     @str2, cast(itemid as char(5)), 
                                     @str3, cast(itemid as char(5)), 
                                     @str4, cast(itemid as char(5)), 
                                     @str5),
                   @from)
from items
where itemid>22000 
      and itemid<24000;

exec sp_executesql @sql;