1 题目

这确实是一个真实的面试题,琢磨一下吧!知识不用,就会丢掉,我太依赖各种框架和dll了,已经忘记了最基本的东西。有多久没有写过SQL了,我已经不记得了。

已知表信息如下:

Department(depID, depName),depID 系编号,DepName系名

Student(stuID, name, depID) 学生编号,姓名,系编号

Score(stuID, category, score) 学生编码,科目,成绩

找出每一个系的最高分,并且按系编号,学生编号升序排列,要求顺序输出以下信息:

系编号,系名,学生编号,姓名,总分

2 实验

USE [test]
GO
/****** Object: Table [dbo].[Score] Script Date: 05/11/2015 23:16:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Score](
[stuID] [int] NOT NULL,
[category] [varchar](50) NOT NULL,
[score] [int] NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (1, N'英语', 80)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (2, N'数学', 80)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (1, N'数学', 70)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (2, N'英语', 89)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (3, N'英语', 81)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (3, N'数学', 71)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (4, N'数学', 91)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (4, N'英语', 61)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (5, N'英语', 91)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (6, N'英语', 89)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (7, N'英语', 77)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (8, N'英语', 97)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (9, N'英语', 57)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (5, N'数学', 87)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (6, N'数学', 89)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (7, N'数学', 80)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (8, N'数学', 81)
INSERT [dbo].[Score] ([stuID], [category], [score]) VALUES (9, N'数学', 84)
/****** Object: Table [dbo].[Department] Script Date: 05/11/2015 23:16:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Department](
[depID] [int] IDENTITY(1,1) NOT NULL,
[depName] [varchar](50) NOT NULL,
PRIMARY KEY CLUSTERED
(
[depID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Department] ON
INSERT [dbo].[Department] ([depID], [depName]) VALUES (1, N'计算机')
INSERT [dbo].[Department] ([depID], [depName]) VALUES (2, N'生物')
INSERT [dbo].[Department] ([depID], [depName]) VALUES (3, N'数学')
SET IDENTITY_INSERT [dbo].[Department] OFF
/****** Object: Table [dbo].[Student] Script Date: 05/11/2015 23:16:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Student](
[stuID] [int] IDENTITY(1,1) NOT NULL,
[stuName] [varchar](50) NOT NULL,
[deptID] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[stuID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Student] ON
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (1, N'计算机张三', 1)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (2, N'计算机李四', 1)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (3, N'计算机王五', 1)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (4, N'生物amy', 2)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (5, N'生物kity', 2)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (6, N'生物lucky', 2)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (7, N'数学_yiming', 3)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (8, N'数学_haoxue', 3)
INSERT [dbo].[Student] ([stuID], [stuName], [deptID]) VALUES (9, N'数学_wuyong', 3)
SET IDENTITY_INSERT [dbo].[Student] OFF
/****** Object: Default [DF__Departmen__depNa__5441852A] Script Date: 05/11/2015 23:16:23 ******/
ALTER TABLE [dbo].[Department] ADD DEFAULT ('') FOR [depName]
GO
/****** Object: Default [DF__Score__category__5EBF139D] Script Date: 05/11/2015 23:16:23 ******/
ALTER TABLE [dbo].[Score] ADD DEFAULT ('') FOR [category]
GO
/****** Object: Default [DF__Score__score__5FB337D6] Script Date: 05/11/2015 23:16:23 ******/
ALTER TABLE [dbo].[Score] ADD DEFAULT ((0)) FOR [score]
GO
/****** Object: Default [DF__Student__stuName__59063A47] Script Date: 05/11/2015 23:16:23 ******/
ALTER TABLE [dbo].[Student] ADD DEFAULT ('') FOR [stuName]
GO
/****** Object: ForeignKey [FK__Student__deptID__59FA5E80] Script Date: 05/11/2015 23:16:23 ******/
ALTER TABLE [dbo].[Student] WITH CHECK ADD FOREIGN KEY([deptID])
REFERENCES [dbo].[Department] ([depID])
GO

准备环境

3 结果

  面试的时候,没有写出来,当时脑袋昏沉沉的。也确实好久没有写复杂的sql语句了。今天花了2到3个小时,终于试出来了。不知道有没有更好的写法?

-- 每个系里的最高分的学生信息
SELECT Department.depID, Department.depName, Student.stuID, stuName, Dscore.scores
FROM Department
LEFT JOIN Student
on department.depID = student.deptID
LEFT JOIN (SELECT Score.stuId, SUM(Score) AS scores
FROM Score
GROUP by stuID
) AS Dscore
on Student.stuID = dScore.stuID
where exists (
select *
from
(
SELECT deptID, MAX(scores) AS topScores
FROM Student
LEFT JOIN
(
SELECT stuID,SUM(score) AS scores
FROM Score
GROUP BY stuID) AS newScore
ON Student.stuID = newScore.stuID
group by deptID) AS depScore
where Department.depID = depScore.deptID and Dscore.scores=depScore.topScores
)
order by Department.depID,Student.stuID;

4 补充

看了那么多的评论,自己写的真的不咋样,可惜今天没有时间细细看了,现在还在公司加班!但百度一下的时间还是有滴,So整理一下相关资料先。

(1)、SQL2005四个排名函数(row_number、rank、dense_rank和ntile)的比较

(2)、关于with as:使用WITH AS提高性能简化嵌套SQL

 5 参考SQL

  正确的答案的结果是一样的,错误的各有各的不同,正确的答案后的性能也各有各的不同,不过呢,暂时没有水平去分析它,但是有空会把这些全部看一遍.谢谢各位啦!【2015-05-13 23:44】

1、pursuer.chen
SELECT B.depID,B.depName,B.stuID ,B.stuName,SUM(A.score )AS SUM_SCORE FROM Score A
INNER JOIN
(SELECT SA.depID,SA.depName,S.stuID,S.stuName FROM Student S
INNER JOIN Score SE ON S.stuID=SE.stuID
INNER JOIN (
SELECT D.depID,D.depName ,MAX(SC.score )AS MX_score FROM Student S INNER JOIN Score SC ON S.stuID=SC.stuID INNER JOIN Department D ON S.deptID=D.depID
GROUP BY D.depID,D.depName ) SA ON SE.score=SA.MX_score AND S.deptID=SA.depID )
B ON A.stuID=B.stuID
GROUP BY B.depID,B.depName,B.stuID ,B.stuName
ORDER BY B.depID,B.stuID
结果正确
1 计算机 2 计算机李四 169
2 生物 4 生物amy 152
2 生物 5 生物kity 178
3 数学 8 数学_haoxue 178 2、Gamain 正确 WITH cte1 as
(
    SELECT
        DISTINCT
        D.depID,
        D.depName,
        S.stuID,
        S.stuName,
    SUM(Sc.score) OVER (PARTITION BY D.depID,S.stuID) as sumScore
    FROM Department D LEFT JOIN Student S ON D.depID=S.deptID
                      LEFT JOIN Score Sc ON Sc.stuID=S.stuID
), cte2 as
(
    SELECT
        DISTINCT
        depID,
        stuID,
    MAX(sumScore) OVER (PARTITION BY depID) as maxScore
    FROM
    cte1
)
SELECT
    c1.depID,
    c1.depName,
    c1.stuID,
    c1.stuName,
    c1.sumScore
from cte2 c2 INNER JOIN cte1 c1
    ON c1.depID=c2.depID AND c1.stuID=c2.stuID and c1.sumScore=c2.maxScore; 3、飞不动 正确
use test; select
e.*
from
(
select c.depID,c.depName,a.stuID,b.stuName,a.total from
(select stuID,sum(score) as total from Score group by stuID) a
join Student b on b.stuID=a.stuID
join Department c on c.depID=b.deptID
) e
join
(select b.deptID,max(a.total) maxScore from
(select stuID,sum(score) as total from Score group by stuID) a
join Student b on b.stuID=a.stuID
group by b.deptID
) f on e.depID=f.deptID and e.total=f.MaxScore
order by e.depID,e.stuID 4、之路 错误
select
depID,
depName,
stuId,
stuName,
PerTotalScore
from (
select
stuID,
stuName,
depID,
depName,
PerTotalScore,
ROW_NUMBER() OVER(partition by depID order by PerTotalScore) as RowId
from (
select
distinct
s.stuID,
s.stuName,
d.depID,
d.depName,
SUM(c.score) OVER(partition by d.depID,s.stuID) as PerTotalScore
from dbo.student s
JOIN dbo.Department d on s.deptID=d.depID
JOIN dbo.Score c ON s.StuID=c.StuID ) as T ) as TT
WHERE TT.RowId=1
order by depID,stuID 1 计算机 1 计算机张三 150
2 生物 4 生物amy 152
3 数学 9 数学_wuyong 141 5、King兵 正确
WITH a
AS
(SELECT Department.depID, Department.depName, Student.stuID, stuName, Dscore.scores,ROW_NUMBER() OVER(PARTITION BY Department.depID ORDER BY scores DESC) ROWID
FROM Department
LEFT JOIN Student
on department.depID = student.deptID
LEFT JOIN (SELECT Score.stuId, SUM(Score) AS scores
FROM Score
GROUP by stuID
) AS Dscore
on Student.stuID = dScore.stuID),
b
AS
(
SELECT Department.depID, Department.depName, Student.stuID, stuName, Dscore.scores,ROW_NUMBER() OVER(PARTITION BY Department.depID ORDER BY scores DESC) ROWID
FROM Department
LEFT JOIN Student
on department.depID = student.deptID
LEFT JOIN (SELECT Score.stuId, SUM(Score) AS scores
FROM Score
GROUP by stuID
) AS Dscore
on Student.stuID = dScore.stuID
) SELECT depID, depName, stuID, stuName, scores,ROWID FROM a WHERE a.scores = (SELECT MAX(scores) FROM b c WHERE a.depid = c.depid) 6、 怪咖Eric 正确
SELECT bb.deptID ,
cc.depName ,
bb.stuID ,
bb.stuName ,
bb.TotalScore
FROM ( SELECT * ,
RANK() OVER ( PARTITION BY deptID ORDER BY TotalScore DESC ) AS pos
FROM ( SELECT SUM(b.score) AS TotalScore ,
a.stuID ,
a.stuName ,
a.deptID
FROM Student a
JOIN Score b ON a.StuID = b.StuID
GROUP BY a.stuID ,
a.stuName ,
a.deptID
) aa
) bb
JOIN dbo.Department cc ON bb.deptID = cc.depID
JOIN dbo.Student dd ON bb.stuID = dd.stuID
WHERE pos = ''
ORDER BY bb.deptID ,
bb.stuID
7、Michael Jiang 手写 改后正确 use test; SELECT D.*
FROM (
SELECT de.depID,
de.depName,
st.stuID,
st.stuName,
sc.score,
RANK() OVER(
PARTITION BY st.deptID
ORDER BY sc.score DESC
) rowno
FROM Student st
LEFT JOIN Department de
ON de.depID=st.deptID
LEFT JOIN (
SELECT sc.stuID,
SUM(sc.score) score
FROM Score sc
GROUP BY sc.stuID
) sc
ON sc.stuID=st.stuID
) D
WHERE D.rowno = 1 --看错要求,原来只要列出最高分
ORDER BY D.depID, D.rowno 8、正确 Li.zheng
use test;
select * from (
select
(select depName from Department where Department.depID = a.depID) as depName,
(select stuName from Student where Student.stuID = a.stuID) as stuName,
dense_rank() over(partition by depID order by sumScore desc) as rank,
a.sumScore
from
(
select
c.depID,b.stuid,sum(a.score) as sumScore
from
score as a
inner join Student as b on a.stuid = b.stuid
inner join Department as c on c.depID = b.deptID
group by
c.depID,b.stuid
) as a
) as b where b.rank = 1 9、下个路口 错误 漏了并列第一
SELECT *
FROM (
SELECT s1.stuID,s1.stuName,s1.deptID,t.totalScore,d.depName,
ROW_NUMBER() OVER(PARTITION BY d.depID ORDER BY totalScore DESC) AS
Rn
FROM Student AS s1
INNER JOIN (
SELECT s.stuID,SUM(s2.score) AS totalScore FROM Student AS s
INNER JOIN Department AS d ON d.depID = s.deptID
INNER JOIN Score s2 ON s2.stuID = s.stuID
GROUP BY s.stuID
) AS t
ON t.stuID = s1.stuID
INNER JOIN Department AS d
ON d.depID = s1.deptID
) result
WHERE Rn = 1
ORDER BY result.stuID 9、自由_ 正确
select d.depID,d.depName,s.stuID,s.stuName,t.score from Department d left join
(select s.stuID,sum(s.score) as score,st.deptID,
rank() over(partition by st.deptID order by sum(s.score) desc) ra from Score s
left join Student st on s.stuID = st.stuID group by s.stuID,st.deptID) t
on d.depID = t.deptID left join Student s on t.stuID = s.stuID
where t.ra = 1 order by d.depID,s. 10、 手写 改了 之后 错误,
use test;
with Combin AS
(
SELECT MAX(score) AS 最高分,deptID AS 系编号,MAX(a.stuID) AS 学生Id FROM Student a LEFT JOIN Score b ON a.stuID=b.stuID
GROUP BY a.deptID
) SELECT
c.系编号,
(SELECT depName FROM Department d WHERE d.depID=c.系编号 ) AS 系名,
c.学生Id AS '学生编号',
(SELECT stuName FROM Student e WHERE e.stuID=c.学生Id ) AS '姓名',
c.最高分
FROM Combin c
1 计算机 3 计算机王五 89
2 生物 6 生物lucky 91
3 数学 9 数学_wuyong 97 11、 舍长 正确
use test; WITH T1 AS (
SELECT A.DEPID,A.DEPNAME,B.STUID,B.STUNAME,SUM(C.SCORE) AS TotalScore
FROM Department A
INNER JOIN Student B
ON A.DEPID = B.DEPTID
INNER JOIN Score C
ON B.STUID = C.STUID
GROUP BY A.DEPID,A.DEPNAME,B.STUID,B.STUNAME
),
T2 AS (
SELECT *,RANK() OVER(PARTITION BY DEPID ORDER BY TotalScore DESC) AS RankScore FROM T1
)
SELECT * FROM T2 WHERE RankScore = 1 ORDER BY DEPID,STUID 12、Ender.Lu 正确
with
tscore as (select stuID ,sum(score) as score from dbo.Score group by stuID),
tinfo as (select Student.deptID ,Department.depName,dbo.Student.stuID,dbo.Student.stuName,tscore.score from dbo.Student
inner join [dbo].[Department] on dbo.Department.depID = student.deptID
left join tscore on tscore.stuid = Student.stuID),
trank as (
select deptID ,depName,stuID,stuName,score ,rank() over(partition by deptID order by score desc) as level from tinfo
)
select deptID ,depName,stuID,stuName,score from trank where level = 1 order by deptID ,stuID; 13、McJeremy&Fan 正确
select p.totalscore,p.stuid,p.stuname,p.deptid,x.depname from
(
select
dense_rank() over(partition by deptid order by totalscore desc) as num,
a.totalscore,b.stuid,b.stuname,b.deptid
from
(
select stuid,sum(score) as totalscore from score
group by stuid
) a inner join student b on a.stuid=b.stuid
) as p
inner join department x on p.deptid=x.depid
where p.num=1 13、清水无大大鱼 正确
with temp as(
select a.deptid,a.stuID,a.stuName,b.score from student a,(select stuID,sum(score)as score from score group by stuID)b where a.stuID=b.stuID)
select d.depID,d.depName,b.stuID,b.stuName,b.score from Department d,(
select * from temp t where t.score=( select max(score) from temp sc where t.deptid=sc.deptid)) b where d.depID=b.deptID order by depID,stuID 14、 BattleHeart 正确
SELECT D.*,DD.depName FROM (
SELECT C.stuID,
C.TotleScore,
C.stuName,
C.deptID,
DENSE_RANK() OVER(PARTITION BY C.deptID ORDER BY C.TotleScore DESC ) nubid
FROM (SELECT S.stuID,
ST.stuName,
SUM(S.score) AS TotleScore,
ST.deptID
FROM dbo.Student AS ST
INNER JOIN dbo.Score AS S ON S.stuID = ST.stuID
GROUP BY S.stuID,ST.deptID,ST.stuName) AS C) AS D INNER JOIN dbo.Department AS DD
ON DD.depID = D.deptID WHERE D.nubid=1

.NET高级工程师面试题之SQL篇的更多相关文章

  1. Java面试题之基础篇概览

    Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...

  2. web前端面试试题总结---html篇

    HTML Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于 <html> 标签之前.告知浏览器的解析器 ...

  3. 前端面试题(html篇)

    前端面试题(html篇)

  4. 【转】BAT及各大互联网公司2014前端笔试面试题:JavaScript篇

    原文转自:http://blog.jobbole.com/78738/ 很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础更是 ...

  5. 部分常见ORACLE面试题以及SQL注意事项

    部分常见ORACLE面试题以及SQL注意事项 一.表的创建: 一个通过单列外键联系起父表和子表的简单例子如下: CREATE TABLE parent(id INT NOT NULL, PRIMARY ...

  6. (转)BAT及各大互联网公司2014前端笔试面试题--Html,Css篇

    BAT及各大互联网公司2014前端笔试面试题--Html,Css篇   很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础更是 ...

  7. web前端面试试题总结---css篇

    CSS 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有两种, IE 盒子模型.W3C 盒子模型: (2)盒模型: 内容(content).填充(padding).边界(m ...

  8. web前端面试试题总结---javascript篇

    JavaScript 介绍js的基本数据类型. Undefined.Null.Boolean.Number.String. ECMAScript 2015 新增:Symbol(创建后独一无二且不可变的 ...

  9. Oracle SQL篇(一)null值之初体验

           从我第一次正式的写sql语句到现在,已经超过10年的时间了.我写报表,做统计分析和财务对账,我一点点的接触oracle数据库,并尝试深入了解.这条路,一走就是10年,从充满热情,到开始厌 ...

随机推荐

  1. 用collectionview实现瀑布流-转

    算法总体思路 先说一下总体上的思路.既然图片的大小.位置各不一样,我们很自然地会想到需要算出每个item的frame,然后把这些frame赋值给当前item的UICollectionViewLayou ...

  2. CE5 WiFi开关

    WinCE的WiFi开关要依赖于WiFi模块的休眠功能还有模块厂商提供的驱动里面有支持电源管理功能.这里面用的是SDIO86861模块,WinCE5的系统,S3C2416的CPU. 头文件要包括:#i ...

  3. Unity3D研究院之获取摄像机的视口区域

    摄像机分为两种,一种是正交摄像机还有一种是透视摄像机.正交摄像机无论远近它的视口范围永远是固定的,但是透视摄像机是由原点向外扩散性发射,也就是距离越远它的视口区域也就越大.那么我们如何获取距离摄像机任 ...

  4. springmvc权限过滤器

    package com.zbb.cn.filter; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; ...

  5. SQL总结(五)存储过程

    SQL总结(五)存储过程 概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句. 创建存储过程语法 CREATE proc | procedure pro ...

  6. Kibana安装及部署

    安装及部署 一.环境配置 操作系统:Cent OS 7 Kibana版本:3.1.2 JDK版本:1.7.0_51 SSH Secure Shell版本:XShell 5 二.操作过程 1.下载指定版 ...

  7. 【uTenux实验】互斥体

    互斥体,维基百科中交互斥锁.其定义是这样的:互斥锁(英语:英语:Mutual exclusion,缩写 Mutex)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制 ...

  8. ORACLE创建表之前判断表是否存在与SQL Server 对比使用

    在SQL Server 数据库中,我们在创建表之前删除表,有if exit()这样的语句,但是在oracle中却没有.如果直接使用drop table那么如果表不存在会报错,导致后续语句无法运行.因此 ...

  9. Windows下查看进程及结束进程命令[转]

    Windows下查看进程及结束进程命令 1)查看占用8080端口的进程号 >netstat –aon | findstr “8080” 结果:TCP    0.0.0.0:8080        ...

  10. HTC Vive开发笔记之手柄控制

    怎么安装设备,配置环境我就不说了,自行百度,教程很多也很简单.接下来说下Vive手柄的控制. 手柄是HTC Vive的重要交互手段,我们通过第一个图片应该对其有一个直观的了解了,总共是九个按钮: 第一 ...