• Sql Server 面试题


    1.用一条SQL语句 查询出每门课都大于80分的学生姓名

    name   kecheng   fenshu
    张三     语文       81
    张三     数学       75
    李四     语文       76
    李四     数学       90
    王五     语文       81
    王五     数学       100
    王五     英语       90

    A: select distinct name from table where name not in (select distinct name from table where fenshu<=80)

    2.学生表 如下:
    自动编号   学号   姓名 课程编号 课程名称 分数
    1        2005001 张三 0001      数学    69
    2        2005002 李四 0001      数学    89
    3        2005001 张三 0001      数学    69
    删除除了自动编号不同,其他都相同的学生冗余信息

    A: delete tablename where 自动编号 not in(select min(自动编号) from tablename group by 学号,姓名,课程编号,课程名称,分数)

    一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
    你先按你自己的想法做一下,看结果有我的这个简单吗?

    答:select a.name, b.name
    from team a, team b
    where a.name < b.name


    请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。
    AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
    数据库名:JcyAudit,数据集:Select * from TestDB

    答:select a.*
    from TestDB a
    ,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b
    where a.Occmonth=b.Occmonth and a.DebitOccur>b.Debit101ccur

    ************************************************************************************

    面试题:怎么把这样一个表儿
    year month amount
    1991   1     1.1
    1991   2     1.2
    1991   3     1.3
    1991   4     1.4
    1992   1     2.1
    1992   2     2.2
    1992   3     2.3
    1992   4     2.4
    查成这样一个结果
    year m1 m2 m3 m4
    1991 1.1 1.2 1.3 1.4
    1992 2.1 2.2 2.3 2.4

    答案一、
    select year,
    (select amount from aaa m where month=1 and m.year=aaa.year) as m1,
    (select amount from aaa m where month=2 and m.year=aaa.year) as m2,
    (select amount from aaa m where month=3 and m.year=aaa.year) as m3,
    (select amount from aaa m where month=4 and m.year=aaa.year) as m4
    from aaa group by year

    ************************************************************************************

    精妙的SQL语句!
    精妙SQL语句
    作者:不详 发文时间:2003.05.29 10:55:05

    说明:复制表(只复制结构,源表名:a 新表名:b)

    SQL: select * into b from a where 1<>1

    说明:拷贝表(拷贝数据,源表名:a 目标表名:b)

    SQL: insert into b(a, b, c) select d,e,f from b;

    说明:显示文章、提交人和最后回复时间

    SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

    说明:外连接查询(表名1:a 表名2:b)

    SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

    说明:日程安排提前五分钟提醒

    SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

    说明:两张关联表,删除主表中已经在副表中没有的信息

    SQL:

    delete from info where not exists ( select * from infobz where info.infid=infobz.infid )

    说明:四表联查问题:

    SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

    说明:得到表中最小的未使用的ID号

    SQL:

    SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID

    FROM Handle

    WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)


    *******************************************************************************

    有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value换为A中对应的value
    这道题的SQL语句怎么写?

    update   b   set   b.value=(select   a.value   from   a   where   a.key=b.key)   where   b.id   in(select   b.id   from   b,a   where   b.key=a.key);

    ***************************************************************************

    高级sql面试题

    原表:
    courseid coursename score
    -------------------------------------
    1 java 70
    2 oracle 90
    3 xml 40
    4 jsp 30
    5 servlet 80
    -------------------------------------
    为了便于阅读,查询此表后的结果显式如下(及格分数为60):
    courseid coursename score mark
    ---------------------------------------------------
    1 java 70 pass
    2 oracle 90 pass
    3 xml 40 fail
    4 jsp 30 fail
    5 servlet 80 pass
    ---------------------------------------------------

    *******************************************************************************

    1.原表:

    id proid proname
    1 1 M
    1 2 F
    2 1 N
    2 2 G
    3 1 B
    3 2 A
    查询后的表:

    id pro1 pro2
    1 M F
    2 N G
    3 B A
    写出查询语句

    2.sql求解
    表a
    列 a1 a2
    记录

    1 a
    1 b
    2 x
    2 y
    2 z
    用select能选成以下结果吗?
    1 ab
    2 xyz

    关于论坛上那个SQL微软面试题

    问题:

    一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息


    这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第一天)

    返回的记录集是一个100天*100个用户的纪录集

    下面是我的思路:

    1.创建表并插入测试数据:我们要求username从1-100
    CREATE TABLE [dbo].[TABLE2] (
    [username] [varchar] (50) NOT NULL , --用户名
    [outdate] [datetime] NOT NULL , --日期
    [cash] [float] NOT NULL --余额
    ) ON [PRIMARY

    declare @i int
    set @i=1
    while @i<=100
    begin
        insert table2 values(convert(varchar(50),@i),'2001-10-1',100)
        insert table2 values(convert(varchar(50),@i),'2001-11-1',50)
        set @i=@i+1
    end
    insert table2 values(convert(varchar(50),@i),'2001-10-1',90)

    select * from table2 order by outdate,convert(int,username)

    2.组合查询语句:
    a.我们必须返回一个从第一天开始到100天的纪录集:
    如:2001-10-1(这个日期是任意的)到 2002-1-8
    由于第一天是任意一天,所以我们需要下面的SQL语句:
    select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
    from table2
    group by username
    order by convert(int,username)
    这里的奥妙在于:
    convert(int,username)-1(记得我们指定用户名从1-100 :-))
    group by username,min(outdate):第一天就可能每个用户有多个纪录。
    返回的结果:
    outdate                                               
    ------------------------------------------------------
    2001-10-01 00:00:00.000
    .........
    2002-01-08 00:00:00.000

    b.返回一个所有用户名的纪录集:
    select distinct username from table2
    返回结果:
    username                                         
    --------------------------------------------------
    1
    10
    100
    ......
    99

    c.返回一个100天记录集和100个用户记录集的笛卡尔集合:
    select * from
    (
    select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
    from table2
    group by username
    order by convert(int,username)

    ) as A
    CROSS join
    (
    select distinct username from table2
    ) as B
    order by outdate,convert(int,username)
    返回结果100*100条纪录:
    outdate                            username
    2001-10-01 00:00:00.000            1
    ......
    2002-01-08 00:00:00.000            100

    d.返回当前所有用户在数据库的有的纪录:
    select outdate,username,min(cash) as cash from table2
    group by outdate,username

    order by outdate,convert(int,username)
    返回纪录:
    outdate                            username    cash
    2001-10-01 00:00:00.000            1          90
    ......
    2002-01-08 00:00:00.000            100        50

    e.将c中返回的笛卡尔集和d中返回的纪录做left join:
    select C.outdate,C.username,
    D.cash
    from
    (
    select * from
    (
    select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
    from table2
    group by username
    order by convert(int,username)
    ) as A
    CROSS join
    (
    select distinct username from table2
    ) as B
    ) as C
    left join
    (
    select outdate,username,min(cash) as cash from table2
    group by outdate,username
    ) as D
    on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)

    order by C.outdate,convert(int,C.username)
    注意:用户在当天如果没有纪录,cash字段返回NULL,否则cash返回每个用户当天的余额
    outdate                            username    cash
    2001-10-01 00:00:00.000            1          90
    2001-10-01 00:00:00.000            2          100
    ......
    2001-10-02 00:00:00.000            1          90

    2001-10-02 00:00:00.000            2          NULL <--注意这里
    ......

    2002-01-08 00:00:00.000            100        50

    f.好了,现在我们最后要做的就是,如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额(由于我们使用order by cash,所以返回top 1纪录即可,使用min应该也可以),这个余额即为当前的余额:
    case isnull(D.cash,0)
    when 0 then
    (
    select top 1 cash from table2 where table2.username=C.username
    and datediff(d,C.outdate,table2.outdate)<0
    order by table2.cash
    )
    else D.cash
    end as cash

    g.最后组合的完整语句就是
    select C.outdate,C.username,
    case isnull(D.cash,0)
    when 0 then
    (
    select top 1 cash from table2 where table2.username=C.username
    and datediff(d,C.outdate,table2.outdate)<0
    order by table2.cash
    )
    else D.cash
    end as cash
    from
    (
    select * from
    (
    select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
    from table2
    group by username
    order by convert(int,username)
    ) as A
    CROSS join
    (
    select distinct username from table2
    ) as B
    ) as C
    left join
    (
    select outdate,username,min(cash) as cash from table2
    group by outdate,username
    ) as D
    on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)

    order by C.outdate,convert(int,C.username)

    返回结果:
    outdate                                 username        cash
    2001-10-01 00:00:00.000    1                    90
    2001-10-01 00:00:00.000    2                   100
    ......
    2002-01-08 00:00:00.000    100                50

    ***********************************************************************************

    取出sql表中第31到40的记录(以自动增长ID为主键)

    *从数据表中取出第n条到第m条的记录*/

    declare @m int
    declare @n int
    declare @sql varchar(800)
    set @m=40
    set @n=31
    set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in(
    select top '+ str(@n-1) + 'autoid from idetail)'
    exec(@sql)

    select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id

    --------------------------------------------------------------------------------

    select top 10 * from t where id in (select top 40 id from t order by id) order by id desc


    *******************************************************************************

    一道面试题,写sql语句

    有表a存储二叉树的节点,要用一条sql语句查出所有节点及节点所在的层.
    表a
    c1 c2 A ----------1
    ---- ---- /
    A B B C --------2
    A C / /
    B D D N E ------3
    C E /
    D F F K I ---4
    E I
    D K
    C N


    所要得到的结果如下

    jd cs
    ----- ----
    A 1
    B 2
    C 2
    D 3
    N 3
    E 3
    F 4
    K 4
    I 4
    有高手指导一下,我只能用pl/sql写出来,请教用一条sql语句的写法

    SQL> select c2, level + 1 lv
    2 from test start
    3 with c1 = 'A'
    4 connect by c1 = prior c2
    5 union
    6 select 'A', 1 from dual
    7 order by lv;

    C2 LV
    -- ----------
    A 1
    B 2
    C 2
    D 3
    E 3
    N 3
    F 4
    I 4
    K 4

    已选择9行。


    ---------------------------------------------------------------

    1.一道SQL语句面试题,关于group by
    表内容:
    2005-05-09 胜
    2005-05-09 胜
    2005-05-09 负
    2005-05-09 负
    2005-05-10 胜
    2005-05-10 负
    2005-05-10 负

    如果要生成下列结果, 该如何写sql语句?

                胜 负
    2005-05-09 2 2
    2005-05-10 1 2
    ------------------------------------------
    create table #tmp(rq varchar(10),shengfu nchar(1))

    insert into #tmp values('2005-05-09','胜')
    insert into #tmp values('2005-05-09','胜')
    insert into #tmp values('2005-05-09','负')
    insert into #tmp values('2005-05-09','负')
    insert into #tmp values('2005-05-10','胜')
    insert into #tmp values('2005-05-10','负')
    insert into #tmp values('2005-05-10','负')

    1)select rq, sum(case when shengfu='胜' then 1 else 0 end)'胜',sum(case when shengfu='负' then 1 else 0 end)'负' from #tmp group by rq
    2) select N.rq,N.勝,M.負 from (
    select rq,勝=count(*) from #tmp where shengfu='胜'group by rq)N inner join
    (select rq,負=count(*) from #tmp where shengfu='负'group by rq)M on N.rq=M.rq
    3)select a.col001,a.a1 胜,b.b1 负 from
    (select col001,count(col001) a1 from temp1 where col002='胜' group by col001) a,
    (select col001,count(col001) b1 from temp1 where col002='负' group by col001) b
    where a.col001=b.col001

    2.请教一个面试中遇到的SQL语句的查询问题
    表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列。
    ------------------------------------------
    select (case when a>b then a else b end ),
    (case when b>c then b esle c end)
    from table_name

    3.面试题:一个日期判断的sql语句?
    请取出tb_send表中日期(SendTime字段)为当天的所有记录?(SendTime字段为datetime型,包含日期与时间)
    ------------------------------------------
    select * from tb where datediff(dd,SendTime,getdate())=0

    4.有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路):
       大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。
           显示格式:
           语文              数学                英语
           及格              优秀                不及格   
    ------------------------------------------
    select
    (case when 语文>=80 then '优秀'
            when 语文>=60 then '及格'
    else '不及格') as 语文,
    (case when 数学>=80 then '优秀'
            when 数学>=60 then '及格'
    else '不及格') as 数学,
    (case when 英语>=80 then '优秀'
            when 英语>=60 then '及格'
    else '不及格') as 英语,
    from table

    5.在sqlserver2000中请用sql创建一张用户临时表和系统临时表,里面包含两个字段ID和IDValues,类型都是int型,并解释下两者的区别?
    ------------------------------------------
    用户临时表:create table #xx(ID int, IDValues int)
    系统临时表:create table ##xx(ID int, IDValues int)

    区别:
    用户临时表只对创建这个表的用户的Session可见,对其他进程是不可见的.
    当创建它的进程消失时这个临时表就自动删除.

    全局临时表对整个SQL Server实例都可见,但是所有访问它的Session都消失的时候,它也自动删除.

    6.sqlserver2000是一种大型数据库,他的存储容量只受存储介质的限制,请问它是通过什么方式实现这种无限容量机制的。
    ------------------------------------------
    它的所有数据都存储在数据文件中(*.dbf),所以只要文件够大,SQL    Server的存储容量是可以扩大的.

    SQL Server 2000 数据库有三种类型的文件:

    主要数据文件
    主要数据文件是数据库的起点,指向数据库中文件的其它部分。每个数据库都有一个主要数据文件。主要数据文件的推荐文件扩展名是 .mdf。

    次要数据文件
    次要数据文件包含除主要数据文件外的所有数据文件。有些数据库可能没有次要数据文件,而有些数据库则有多个次要数据文件。次要数据文件的推荐文件扩展名是 .ndf。

    日志文件
    日志文件包含恢复数据库所需的所有日志信息。每个数据库必须至少有一个日志文件,但可以不止一个。日志文件的推荐文件扩展名是 .ldf。

    7.请用一个sql语句得出结果
    从table1,table2中取出如table3所列格式数据,注意提供的数据及结果不准确,只是作为一个格式向大家请教。
    如使用存储过程也可以。

    table1

    月份mon 部门dep 业绩yj
    -------------------------------
    一月份      01      10
    一月份      02      10
    一月份      03      5
    二月份      02      8
    二月份      04      9
    三月份      03      8

    table2

    部门dep      部门名称dname
    --------------------------------
          01      国内业务一部
          02      国内业务二部
          03      国内业务三部
          04      国际业务部

    table3 (result)

    部门dep 一月份      二月份      三月份
    --------------------------------------
          01      10        null      null
          02      10         8        null
          03      null       5        8
          04      null      null      9

    ------------------------------------------
    1)
    select a.部门名称dname,b.业绩yj as '一月份',c.业绩yj as '二月份',d.业绩yj as '三月份'
    from table1 a,table2 b,table2 c,table2 d
    where a.部门dep = b.部门dep and b.月份mon = '一月份' and
    a.部门dep = c.部门dep and c.月份mon = '二月份' and
    a.部门dep = d.部门dep and d.月份mon = '三月份' and
    2)
    select a.dep,
    sum(case when b.mon=1 then b.yj else 0 end) as '一月份',
    sum(case when b.mon=2 then b.yj else 0 end) as '二月份',
    sum(case when b.mon=3 then b.yj else 0 end) as '三月份',
    sum(case when b.mon=4 then b.yj else 0 end) as '四月份',
    sum(case when b.mon=5 then b.yj else 0 end) as '五月份',
    sum(case when b.mon=6 then b.yj else 0 end) as '六月份',
    sum(case when b.mon=7 then b.yj else 0 end) as '七月份',
    sum(case when b.mon=8 then b.yj else 0 end) as '八月份',
    sum(case when b.mon=9 then b.yj else 0 end) as '九月份',
    sum(case when b.mon=10 then b.yj else 0 end) as '十月份',
    sum(case when b.mon=11 then b.yj else 0 end) as '十一月份',
    sum(case when b.mon=12 then b.yj else 0 end) as '十二月份',
    from table2 a left join table1 b on a.dep=b.dep

    8.华为一道面试题
    一个表中的Id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数。
    ------------------------------------------
    select id, Count(*) from tb group by id having count(*)>1
    select * from(select count(ID) as count from table group by ID)T where T.count>1

     
     
    分类: sql server
     
    1
    1
     
    (请您对文章做出评价)
     
    » 下一篇:silverlight 窗体切换 与 窗体之间传值的实现
  • 相关阅读:
    JS计算字符串长度(兼容后端PHP)
    使用iview-admin2构建的项目,热更新无法启动
    关于HSTS的总结
    (转)javascript兼容问题总结
    js写一个通讯录
    HTML5+通讯录获取指定多个人的信息
    MUI封装的选择器调用
    心得小细节(一)
    读后感(一) web运作原理探析
    码农和软件开发工程师
  • 原文地址:https://www.cnblogs.com/mingxuantongxue/p/4495434.html
Copyright © 2020-2023  润新知