zoukankan      html  css  js  c++  java
  • .NET高级工程师面试题之SQL篇

    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 = '1'
    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
  • 相关阅读:
    冷门JS技巧
    JavaScript小技巧整理篇(非常全)
    JS实现标签页切换效果
    MySQL主从配置详解
    mysql主从复制(超简单)
    1.4isAlive()方法
    1.3currentThread()方法
    1.2.4注意Sysyem.out.println与i--
    1.2.3实例变量与线程安全
    1.2.2实现Runnable接口
  • 原文地址:https://www.cnblogs.com/tianxue/p/4493260.html
Copyright © 2011-2022 走看看