`
guomingzhang2008
  • 浏览: 161601 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

从【各大软件公司笔试压轴题】学习SQL语句

阅读更多
从博客园中看到一篇文章,介绍大软件公司面试时常常会出的两道SQL题(见附录)。


我觉得受益很多,在此之前,我一直觉得,SQL2008似乎提供了这方面的支持,但更低的版本,包括2005,非游标做不出来(水平够菜)。总结心得如下:


1、    强大的group by

1  select stdname,
2  isnull(sum( case  stdsubject when  ' 化学 '  then Result end), 0 ) [化学],
3  isnull(sum( case  stdsubject when  ' 数学 '  then Result end), 0 ) [数学],
4  isnull(sum( case  stdsubject when  ' 物理 '  then Result end), 0 ) [物理],
5  isnull(sum( case  stdsubject when  ' 语文 '  then Result end), 0 ) [语文]
6  from #student
7  group by stdname

在这里,group by与sum + case结合,可以将表1中的记录(行)变成表2的字段(列)。Sum里面如果没有case,那么出来的值,只能是全部科目的总和,用了case以后,就是某科的成绩;然后这里用了好几个sum,每个科目一个sum,于是表1中本来某人某科占一条记录的“行”就变成了表2里某人一条记录,每科做一个字段了。


这种心思巧妙和对语法的熟练运用让人击节赞叹。


2、    利用select from (select from)的模式生成SQL语句

1  declare @sql varchar( 4000 )
2  set  @sql  =   ' select stdname ' 
3  select @sql  =  @sql  +   ' ,isnull(sum(case stdsubject when  ''' + stdsubject + '''  then Result end),0) [ ' + stdsubject + ' ] ' 
4  from (select distinct stdsubject from #student)  as  a
5  select @sql  =  @sql + '  from #student group by stdname ' 
6  print @sql
7  exec(@sql)


为了自动写上所有的科目,这里先将科目信息提炼出来:

4  from (select distinct stdsubject from #student)  as  a

利用之拼接生成SQL语句。当然现实中,如果#student表很大,这种做法并不妥,应该都有一个专门的科目类别表的。


3、    在临时库中提炼出字段名。临时表是真实存在的表,保存在[tempdb]中,可以利用object_id('tempdb.dbo.表名')的方式获得字段信息。

============================================

附录:

http://www.cnblogs.com/zhanglei644213943/archive/2009/12/27/1633356.html




      纵览各大社区、论坛,各大 ORM框架火得不行了,如NHibernate、LINQ to SQL、ADO.NET Entity framework等,还有最近市场上出版的一本叫《领域驱动设计与模式实战》,里面也凸显了不少NHibernate在领域驱动设计中的作用与地位,也算是第一本与NHibernate相关的书籍吧!不过就NHibernate而言还是没有官方文档介绍得详细呵呵,园子里Kiler 已经把他翻译成中文版的了,收益一大片仅仅是CET-4的人。不管你是用NHibernate也好,还是用LINQ to SQL也好,用profiler一跟踪,执行的都是SQL语句,所以所SQL是根。特别是对于那些以数据为中心的应用系统,在数据库中实现复杂的存储过程,复杂的报表查询,还是直接SQL来得痛快。当然 对于那些在基于.NET的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,NHibernate是最有用的。不管怎样,NHibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一系列的对象去(官方文档)。

      有点跑题了,不再啰嗦----直接晾出压轴题。

压轴题第一问

1.把表一转换为表二

表一:                                                                     



表二:



数据库代码如下:

  代码
1  DROP table #student
2  CREATE TABLE #student (stdname nvarchar( 10 ),stdsubject nvarchar( 10 ),result  int )
3  INSERT INTO #student VALUES ( ' 张三 ' , ' 语文 ' , 80 )
4  INSERT INTO #student values ( ' 张三 ' , ' 数学 ' , 90 )
5  INSERT INTO #student VALUES ( ' 张三 ' , ' 物理 ' , 85 )
6  INSERT INTO #student VALUES ( ' 李四 ' , ' 语文 ' , 85 )
7  INSERT INTO #student values ( ' 李四 ' , ' 数学 ' , 92 )
8  INSERT INTO #student VALUES ( ' 李四 ' , ' 物理 ' , 82 )
9  INSERT INTO #student VALUES ( ' 李四 ' , ' 化学 ' , 82 )
10  INSERT INTO #student VALUES ( ' 李四 ' , ' 化学 ' , 82 )
11  SELECT  *  FROM #student
可能很多老手们,一看到这题目就有了答案。当然,贴出答案来不是我的目的,我要带着SQL新手们重构到答案。用MVP李建忠老师最爱说的话就是------我不建议一上来就套用模式,而应该从重构到模式。

首先大家会想到分两组

1  select stdname,····,from #student group by stdname
然后······中间该写什么呢?

  代码
1  case  stdsubject when  ' 化学 '  then Result end
2  case  stdsubject when  ' 语文 '  then Result end
3  case  stdsubject when  ' ··· '  then Result end
4  case  stdsubject when  ' ··· '  then Result end
5  case  stdsubject when  ' ··· '  then Result end
表二里面得0是哪里来的呢?

  代码
1  isnull(sum( case  stdsubject when  ' 化学 '  then Result end), 0 )
2  isnull(sum( case  stdsubject when  ' 语文 '  then Result end), 0 )
3  isnull(sum( case  stdsubject when  ' ··· '  then Result end), 0 )
4  isnull(sum( case  stdsubject when  ' ··· '  then Result end), 0 )
5  isnull(sum( case  stdsubject when  ' ··· '  then Result end), 0 )
所以得出:

  代码
1  select stdname,
2  isnull(sum( case  stdsubject when  ' 化学 '  then Result end), 0 ) [化学],
3  isnull(sum( case  stdsubject when  ' 数学 '  then Result end), 0 ) [数学],
4  isnull(sum( case  stdsubject when  ' 物理 '  then Result end), 0 ) [物理],
5  isnull(sum( case  stdsubject when  ' 语文 '  then Result end), 0 ) [语文]
6  from #student
7  group by stdname
然后得出答案:

  代码
1  declare @sql varchar( 4000 )
2  set  @sql  =   ' select stdname ' 
3  select @sql  =  @sql  +   ' ,isnull(sum(case stdsubject when  ''' + stdsubject + '''  then Result end),0) [ ' + stdsubject + ' ] ' 
4  from (select distinct stdsubject from #student)  as  a
5  select @sql  =  @sql + '  from #student group by stdname ' 
6  print @sql
7  exec(@sql)

压轴题第二问:把表二转化为表一

表一:



表二:



数据库代码如下:

  代码
1  DROP table #student2
2  CREATE TABLE #student2 (stdname nvarchar( 10 ),化学  int ,数学  int ,物理  int  ,语文  int  )
3  INSERT INTO #student2 VALUES ( ' 李四 ' , 164 , 92 , 82 , 85 )
4  INSERT INTO #student2 VALUES ( ' 张三 ' , 0 , 90 , 85 , 80 )
5  SELECT  *  FROM #student2 
看到这题,直接想到:

  代码
1  SELECT ' 李四 ' as  stdname,stdname = ' 化学 ' , 化学  as  result from #student2  where  stdname = ' 李四 '
2  union all
3  SELECT ' 李四 ' as  stdname,stdname = ' 数学 ' , 数学  as  result from #student2  where  stdname = ' 李四 '
4  union all
5  SELECT ' 李四 ' as  stdname,stdname = ' 物理 ' , 物理  as  result from #student2  where  stdname = ' 李四 '
6  union all
7  SELECT ' 李四 ' as  stdname,stdname = ' 语文 ' , 语文  as  result from #student2  where  stdname = ' 李四 '  
  8  union all
9  SELECT ' 张三 ' as  stdname,stdname = ' 化学 ' , 化学  as  result from #student2  where  stdname = ' 张三 '
10  union all
11  SELECT ' 张三 ' as  stdname,stdname = ' 数学 ' , 数学  as  result from #student2  where  stdname = ' 张三 '
12  union all
13  SELECT ' 张三 ' as  stdname,stdname = ' 物理 ' , 物理  as  result from #student2  where  stdname = ' 张三 '
14  union all
15  SELECT ' 张三 ' as  stdname,stdname = ' 语文 ' , 语文  as  result from #student2  where  stdname = ' 张三 '
重构到:

  代码
1  declare @sql2 varchar( 4000 )
2    set  @sql2  =   '' 
3  SELECT @sql2 = @sql2 + 
4  ' SELECT ''' + stdname + ''' as stdname,stdname= '' 化学 '' , 化学 as result from #student2 where stdname= ''' + stdname + '''
5  union all
6  SELECT ''' +stdname+ ''' as  stdname,stdname = '' 数学 '' , 数学  as  result from #student2  where  stdname = ''' +stdname+ '''
7  union all
8  SELECT ''' +stdname+ ''' as  stdname,stdname = '' 物理 '' , 物理  as  result from #student2  where  stdname = ''' +stdname+ '''
9  union all
10  SELECT ''' +stdname+ ''' as  stdname,stdname = '' 语文 '' , 语文  as  result from #student2  where  stdname = ''' +stdname+ '''  union all  '
11  from (SELECT stdname FROM #student2)  as  a
12  SELECT @sql2  =  LEFT(@sql2,LEN(@sql2)  -   10 )
13  PRINT(@sql2)
14  exec(@sql2)
如果要求不能出现  化学  数学  物理 语文 这样的关键字,那么可以这样写:

  代码
1  select [name] into #tmpCloumns
2  from tempdb.dbo.syscolumns
3  where  id = object_id( ' tempdb.dbo.#student2 ' )
4  and [name] <> ' stdname '
5  select  *   from #tmpCloumns

7  declare @strSql nvarchar( 800 )
8  select @strSql = ''
9  select @strSql = @strSql + ' union all ' + char ( 10 ) + char ( 13 ) +
10                   ' select [stdname], ''' + [name] + '''  as [科目],[ ' + [name] + ' ] ' + char ( 10 ) + char ( 13 ) +
11                   ' from [#student2] ' + char ( 10 ) + char ( 13 )
12  from #tmpCloumns
13 
14  select @strSql = substring(@strSql, 11 ,len(@strSql)) + ' order by stdname,[科目] '
15  -- print @strSql
16  exec(@strsql) 
这种题目,在各种笔试中出现的概率还是非常大的,大家不用死记。以前有的朋友看着复杂的报表查询,几百行SQL,望而生畏,然后说:"这是哪个SQL超人写的啊!"其实,谁一上来不可能写出那么长的SQL,也是慢慢重构--调试--重构-······



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/leftfist/archive/2009/12/29/5097307.aspx
分享到:
评论

相关推荐

    sql 语句的笔试题

    SQL笔试题 本篇资源主要整理了多道SQL笔试题,涵盖了查询、删除、联合查询、分组等多个方面的知识点。 1. 查询出每门课都大于80分的学生姓名 知识点:子查询、distinct关键字 使用子查询可以实现该需求,子查询...

    软件公司笔试题(sql)

    在软件公司的招聘过程中,SQL(Structured Query Language,结构化查询语言)是常见的一类笔试题,因为它是管理和操作关系数据库的基础。SQL不仅用于数据查询,还涉及到数据的插入、更新、删除以及数据库的设计和...

    各大有名软件公司笔试题

    要想顺利通过有名软件公司的笔试题,请务必看看这些总结,是通过老师才搞到的,还很经典。

    各大软件公司笔试面试题集锦

    这份"各大软件公司笔试面试题集锦"无疑是准备这些挑战的宝贵资源。以下将根据标题、描述以及标签,深入探讨其中可能包含的知识点,并尽可能提供丰富的相关背景和扩展信息。 首先,"软件公司"涵盖了一系列全球或国内...

    西安各大软件公司笔试面试题

    (内部资料) ...西安博达软件笔试题.doc 西安当代医院管理研究院.doc 西安夏日科技笔试题.doc 只列出一部分,希望给正在或正准备找工作的朋友带来帮助,也祝愿大家早日找到心中理想的工作,别忘了留言支持哦!

    【各大软件公司NET工程师笔试压轴题】------不得不看.docx

    【各大软件公司NET工程师笔试压轴题】------不得不看.docx

    南京各大软件公司笔试面试题

    南京-中兴笔试题.doc 南京-中税科技-笔试题.doc 南京-同庆科技笔试题.doc 南京-苏慧面试题.doc 南京-乾坤-笔试题--没用.doc 南京-诺思信数据库基础.doc 没有全部列出,想要找工作的朋友不妨看一看,或许有些帮助,...

    SQL笔试题(转载的)

    这篇文档《2011 SQL笔试题》及其压缩包资源,显然是为了帮助学习者或者应聘者准备SQL相关的面试或笔试而准备的。 SQL的基础知识点包括: 1. **数据类型**:SQL支持多种数据类型,如整数(INT)、浮点数(FLOAT)、...

    武汉各大软件公司笔试面试题(有答案)

    (内部资料) 武汉-英思--ORACLE面试测试题目.doc ...武汉-瑞得软件笔试题.doc 武汉-北大高科页面.doc 只显示部分,希望对正在或正准备找工作的朋友带来帮助,也祝愿大家早日找到心中理想的工作,别忘了留言支持哦!

    sql语句的笔试经典考题

    ### SQL语句笔试经典考题知识点解析 #### 1. SQL语言的特点 - **非过程化**:SQL语言是一种非过程化的语言,这意味着用户只需指定要做什么,而不需要详细说明如何做。这使得SQL易于学习和使用。(选择题1) - **...

    深圳各大软件公司笔试面试题

    深圳-东方伟业笔试部分.doc 深圳-华为C++.doc 深圳-华为Oracle数据库基础知识 ISSUE1.0.doc 深圳-华为SQL总结.doc 深圳-瑞科.doc 没有全部列出,希望能给正在或正准备找工作的朋友带来帮助,也祝愿各位能早日找到...

    广州各大软件公司笔试面试题(有答案)

    广州-飞卓科汇笔试题.doc 广州-虹天电子.doc 广州-乐天科技试题.doc 广州-卧龙在线最新题目.doc 广州-御银科技股份有限公司试卷(C++).doc 只列出一部分,想到广州找软件方面工作的朋友不妨看看,或许有些收获,祝...

    sql server笔试题

    自己整理的SQLserver笔试题。 当做知识点记了 内附答案

    大公司sql笔试题

    1到3年工作经验的 sql面试笔试题(通过面试360,华为,阿里收集)

    sql语句笔试

    sql语句 建表 增加、删除、复杂查询字段

    常见的SQL笔试选择题含答案.docx

    以下是一些关于SQL笔试选择题中的关键知识点: 1. **关系型数据库**:关系型数据库是一种以表格形式存储数据的数据库,其中数据之间的关系可以通过外键进行关联。题目中提到的Oracle和MySql都是典型的关系型数据库...

    大软件公司笔试题大软件公司笔试题大软件公司笔试题

    在准备进入大软件公司的过程中,笔试题是求职者必须面对的重要环节。这些题目通常涵盖了编程基础、算法与数据结构、操作系统、计算机网络、数据库管理、软件工程等多个领域,旨在全面评估候选人的技术实力和问题解决...

    最新各大公司JAVA笔试题及答案

    京东最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案最新各大公司JAVA笔试题及答案...

    嵌入式软件笔试题合集.zip

    嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集嵌入式软件笔试题合集...

Global site tag (gtag.js) - Google Analytics