简单SQL 列转行求教 。。(感谢)

Top_小鑫 2020-09-25 04:52:37
姓名 分数

张三 80
张三 90
张三 100
李四 50
李四 60
王五 90
赵六 40
赵六 50
赵六 60
赵六 70
赵六 80


上面表中的数据 想统计成一个表 如下 多行展示。

姓名 分数 1 分数 2 分数3 分数4 分数5 ......分数10 (一个人最多10条记录 序号123数据 根据A表中创建时间排序)

张三 80 90 100
李四 50 60
王五 90
赵六 40 50 60 70 80
...全文
249 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
KALUO12 2020-09-29
  • 打赏
  • 举报
回复
步骤二写错了一点点,从临时表new中判断如果当前count=1,那么分数1就等当前score,否则null;count=2,分数2就等于score否则 null,依次类推 步骤一语句是:
 select sname,score,@rank:=case when @sname=sname then @rank+1 when @sname:=sname then 1 else 1 end as c  from rows ,(select @rank:=0,@sname='') b;
运行结果如下图:
KALUO12 2020-09-29
  • 打赏
  • 举报
回复
我用mysql 写的 分析步骤: 1.先用变量,将原表按照名字分组给上排名count,就是同名字的就是1,2,3.。。,遇到名字不同重置排名为1,继续1,2,3、、、这样子,生成临时表new 2.然后从临时表new中判断如果当前count=1,那么分数1就等当前score,否则null,count=2,分数2就等于null,依次类推
select sname,
sum(case when  c=1 then score  end) as f1,
sum(case when  c=2 then score  end) as f2,
sum(case when  c=3 then score  end) as f3,
sum(case when  c=4 then score  end) as f4,
sum(case when  c=5 then score  end) as f5,
sum(case when  c=6 then score  end) as f6,
sum(case when  c=7 then score  end) as f7,
sum(case when  c=8 then score  end) as f8,
sum(case when  c=9 then score  end) as f9,
sum(case when  c=10 then score  end) as f10
from (select sname,score,@rank:=case when @sname=sname then @rank+1 when @sname:=sname then 1 else 1 end as c  from rows ,(select @rank:=0,@sname='') b) new  
group by sname;
运行结果是:
wwfxgm 2020-09-28
  • 打赏
  • 举报
回复
谢谢,我每天看看。先理解,再背熟。
中国风 2020-09-27
  • 打赏
  • 举报
回复
这样加print 查看生成过程
DECLARE @Cols VARCHAR(3),@Sql NVARCHAR(4000)='';
SELECT TOP 1 @Cols=COUNT(*) from #T1 GROUP BY 姓名 ORDER BY COUNT(*) DESC
PRINT @Cols
WHILE @Cols>0 --栏位数递减,生成循环
begin
    SELECT @Sql=',MAX(CASE WHEN RN='+@Cols+' THEN RTRIM([分数]) ELSE '''' END) AS 分数'+@Cols+@Sql,@Cols-=1;--递减判断@Col
PRINT @Sql
PRINT @Cols
END 
SET @Sql='SELECT [姓名]'+ @Sql+' FROM (SELECT  *,RN=ROW_NUMBER()OVER(PARTITION BY 姓名 ORDER BY 姓名) from #T1) AS T group by [姓名] ORDER BY [姓名]'
PRINT @Cols
EXEC(@Sql)
Top_小鑫 2020-09-27
  • 打赏
  • 举报
回复
引用 3 楼 中国风 的回复:
e.g.
use Tempdb
go
--> --> 中国风(Roy)生成測試數據
 
if not object_id(N'Tempdb..#T1') is null
	drop table #T1
Go
Create table #T1([姓名] nvarchar(102),[分数] bigint)
Insert #T1
select N'张三',80 union all
select N'张三',90 union all
select N'张三',100 union all
select N'李四',50 union all
select N'李四',60 union all
select N'王五',90 union all
select N'赵六',40 union all
select N'赵六',50 union all
select N'赵六',60 union all
select N'赵六',70 union all
select N'赵六',80
GO
DECLARE @Cols VARCHAR(3),@Sql NVARCHAR(4000)='';
SELECT TOP 1 @Cols=COUNT(*) from #T1 GROUP BY 姓名 ORDER BY COUNT(*) desc
WHILE @Cols>0
	SELECT @Sql=',MAX(CASE WHEN RN='+@Cols+' THEN RTRIM([分数]) ELSE '''' END) AS 分数'+@Cols+@Sql,@Cols-=1;
SET @Sql='SELECT [姓名]'+ @Sql+' FROM (SELECT  *,RN=ROW_NUMBER()OVER(PARTITION BY 姓名 ORDER BY 姓名) from #T1) AS T group by [姓名] ORDER BY [姓名]'
EXEC(@Sql)
/*
姓名	分数1	分数2	分数3	分数4	分数5
李四	50	60			
王五	90				
张三	80	90	100		
赵六	40	50	60	70	80*/
不太好理解,能不能简单化下,让自己看的不那么吃力 ?
中国风 2020-09-27
  • 打赏
  • 举报
回复
在语句中插入 print @sql ,查看每一步生成的语句格式
wwfxgm 2020-09-27
  • 打赏
  • 举报
回复
引用 3 楼 中国风 的回复:
e.g.
use Tempdb
go
--> --> 中国风(Roy)生成測試數據
 
if not object_id(N'Tempdb..#T1') is null
	drop table #T1
Go
Create table #T1([姓名] nvarchar(102),[分数] bigint)
Insert #T1
select N'张三',80 union all
select N'张三',90 union all
select N'张三',100 union all
select N'李四',50 union all
select N'李四',60 union all
select N'王五',90 union all
select N'赵六',40 union all
select N'赵六',50 union all
select N'赵六',60 union all
select N'赵六',70 union all
select N'赵六',80
GO
DECLARE @Cols VARCHAR(3),@Sql NVARCHAR(4000)='';
SELECT TOP 1 @Cols=COUNT(*) from #T1 GROUP BY 姓名 ORDER BY COUNT(*) desc
WHILE @Cols>0
	SELECT @Sql=',MAX(CASE WHEN RN='+@Cols+' THEN RTRIM([分数]) ELSE '''' END) AS 分数'+@Cols+@Sql,@Cols-=1;
SET @Sql='SELECT [姓名]'+ @Sql+' FROM (SELECT  *,RN=ROW_NUMBER()OVER(PARTITION BY 姓名 ORDER BY 姓名) from #T1) AS T group by [姓名] ORDER BY [姓名]'
EXEC(@Sql)
/*
姓名	分数1	分数2	分数3	分数4	分数5
李四	50	60			
王五	90				
张三	80	90	100		
赵六	40	50	60	70	80*/
版主,这个语句,不太好理解,我如何庖丁解牛一下,让自己看的不那么吃力 ?
wwfxgm 2020-09-27
  • 打赏
  • 举报
回复
做一个标记,以后用到了再来看。
中国风 2020-09-26
  • 打赏
  • 举报
回复
e.g.
use Tempdb
go
--> --> 中国风(Roy)生成測試數據

if not object_id(N'Tempdb..#T1') is null
drop table #T1
Go
Create table #T1([姓名] nvarchar(102),[分数] bigint)
Insert #T1
select N'张三',80 union all
select N'张三',90 union all
select N'张三',100 union all
select N'李四',50 union all
select N'李四',60 union all
select N'王五',90 union all
select N'赵六',40 union all
select N'赵六',50 union all
select N'赵六',60 union all
select N'赵六',70 union all
select N'赵六',80
GO
DECLARE @Cols VARCHAR(3),@Sql NVARCHAR(4000)='';
SELECT TOP 1 @Cols=COUNT(*) from #T1 GROUP BY 姓名 ORDER BY COUNT(*) desc
WHILE @Cols>0
SELECT @Sql=',MAX(CASE WHEN RN='+@Cols+' THEN RTRIM([分数]) ELSE '''' END) AS 分数'+@Cols+@Sql,@Cols-=1;
SET @Sql='SELECT [姓名]'+ @Sql+' FROM (SELECT *,RN=ROW_NUMBER()OVER(PARTITION BY 姓名 ORDER BY 姓名) from #T1) AS T group by [姓名] ORDER BY [姓名]'
EXEC(@Sql)
/*
姓名 分数1 分数2 分数3 分数4 分数5
李四 50 60
王五 90
张三 80 90 100
赵六 40 50 60 70 80*/
wwfxgm 2020-09-26
  • 打赏
  • 举报
回复
楼主也可以参考这个帖子,都差不多的。
https://bbs.csdn.net/topics/392397857
qq_25073223 2020-09-25
  • 打赏
  • 举报
回复
行转列的示例分享 有疑问及时沟通!

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧