设为首页 加入收藏

TOP

一道合并成绩最高科目的解决方法
2014-11-24 02:54:42 来源: 作者: 【 】 浏览:3
Tags:一道 合并 成绩 高科 目的 解决 方法

昨天在群里一位网友抛出这样的问题:
name 语文 数学 英语
张三 75 90 85
李四 80 85 85

获得表,查询每个 name 成绩最高的学科, 若有相同,并列
name 成绩 科目
张三 90 数学
李四 85 数学,英语

我的方案:
[sql]
CREATE TABLE [dbo].[ChengJi2](
[姓名] [nchar](10) NULL,
[成绩] [int] NULL,
[科目] nchar(100) NULL,
) ON [PRIMARY]
-------------------------------------
Create Function [dbo].[Getkemu](
@姓名 char(10)=null)
returns varchar(8000)
as
begin
declare @r varchar(8000)
set @r= ' '
select @r=@r+ ', '+ rtrim(CAST (科目 as varchar)) from ChengJi2 where 姓名=@姓名
return stuff(@r,1,2, ' ')
end
------------------------------------
Insert into ChengJi2(姓名,成绩,科目) SELECT B.* FROM (
select 姓名,MAX (成绩) 成绩 from(
SELECT 姓名, 语文 as 成绩,'语文' 科目
FROM ChengJi
union all
SELECT 姓名, 数学 as 成绩,'数学' 科目
FROM ChengJi
union all
SELECT 姓名, 英语 as 成绩,'英语' 科目
FROM ChengJi ) T
group by 姓名) A INNER JOIN
(
select 姓名,MAX (成绩) 成绩,科目 from(
SELECT 姓名, 语文 as 成绩,'语文' 科目
FROM ChengJi
union all
SELECT 姓名, 数学 as 成绩,'数学' 科目
FROM ChengJi
union all
SELECT 姓名, 英语 as 成绩,'英语' 科目
FROM ChengJi ) T
group by 姓名,科目) B ON A.姓名=B.姓名 and A.成绩=B.成绩
-------------------------------------------------------------
select 姓名,成绩,dbo.Getkemu(姓名) as 科目 from ChengJi2
group by 姓名, 成绩 -www.2cto.com-

网友一的方案:
[sql]
select * into #tb
from(
select '张三' as name,60 as 语文,70 as 数学,80 as 英语
union
select '李四' as name,90 as 语文,70 as 数学,90 as 英语
union
select '王武' as name,80 as 语文,80 as 数学,80 as 英语
) a
----------------
select name,max(成绩) as 成绩,
(select case when 语文=MAX(成绩) then '语文,' else '' end+
case when 数学=MAX(成绩) then '数学,' else '' end+
case when 英语=MAX(成绩) then '英语' else '' end
from #tb ab where ab.name=a.name) as 科目
from
(
select name,语文 as 成绩,'语文' 科目
from #tb
union all
select name,数学 as 成绩,'数学' 科目
from #tb
union all
select name,英语 as 成绩,'英语' 科目
from #tb
) a group by a.name
--------------------
drop table #tb
网友二的方案:
[sql]
create table #tmp
(
id int primary key,
[name] varchar(255),
语文 int,
数学 int,
英语 int
)
;
insert into #tmp values(1, '张三', 75, 90, 85);
insert into #tmp values(2, '李四', 80, 85, 85);
with
tree as
(
select [name], 分数, 科目 from #tmp
unpivot
(
分数 for 科目 in (语文, 数学, 英语)
)
as unpvt
),
maxTree as
(
select * from tree t1 where 分数 >= (select max(分数) from tree t2 where t1.name = t2.name)
)
select name, 分数, 科目 = stuff((select ',' + 科目 from maxTree t1 where t1.name = t2.name for xml path('')), 1, 1, '')
from maxTree t2
group by name, 分数
drop table #tmp

总结:
如果单纯作为面试的解决方案,我的方法可行。
如果用函数可能面临不同 数据库的语法的限制。用函数会导致效率比较低下。
网友一给出了比较通用效率高的方案,一开始我也是这个思路,但case when 掌握的不熟练。
网友二是我的方案的改进版


摘自 德仔的专栏
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇SQL数据操作基础(初级)1 下一篇全面接触SQL语法(1)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Sphinx : 高性能SQL (2025-12-24 10:18:11)
·Pandas 性能优化 - (2025-12-24 10:18:08)
·MySQL 索引 - 菜鸟教 (2025-12-24 10:18:06)
·Shell 基本运算符 - (2025-12-24 09:52:56)
·Shell 函数 | 菜鸟教 (2025-12-24 09:52:54)