码迷,mamicode.com
首页 > 数据库 > 详细

关于SQL的几道小题详解

时间:2015-06-15 01:43:42      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

关于SQL的几道小题详解

      当我们拿到题目的时候,并不是急于作答,那样会得不偿失的,而是分析思路,采用什么方法,达到什么目的,还要思考有没有简单的方法或者通用的方法等等,这样才会达到以一当十的效果,这样的惯性思维其实早在我们度高中的时候就被领教了,所谓“万变不离其宗”吧。以下各题来自日常所见,或QQ群,或面试题,或博客园。

     题目一:如下表所示,现需要按照收款员统计收款和退款合计金额。

技术分享

     实现结果需如下显示:

技术分享

      分析:想要的结果(记为表B)和源数据(记为表A)相比,有共同的列(收款员),不同的是表A的金额根据标记和收款员分成了两列,所以这个需求可以用语言表述一下:首先根据收款员分组(group by),然后当标记为“收”时,金额计入收款合计(sum);当标记为“退”时,金额计入退款合计(sum)。当……时……,这不就是SQL的条件判断嘛?盘点SQL的条件语句不多,if……else……case……when……then……else……end。这样问题就迎刃而解了。

     解决方案如下:

 1 with ta as
 2 (select  as 标记,100 as 收款员,150 as 金额
 3  union
 4  select ,100,375
 5  union
 6  select 退,100,78
 7  union select ,200,74
 8 )
 9 
10 select 收款员,sum(case when 标记= then 金额 else 0 end) as 收款合计,
11        sum(case when 标记=退 then 金额 else 0 end) as 退款合计 from ta
12        group by 收款员

      题目二:如下表A(左边)职员信息表,其中ID为职员工号,name为职员姓名;表B(右边)为职员任务分配表,其中ID为职员工号(和表A中ID对应),Task为任务编号。

                              技术分享                                                                                                  技术分享      

     现需求每个职员的任务数。结果如下显示:

技术分享

       其实原题是这样的:只有一张表B,求求每个职员的任务数。没有找到比较好的方法实现,不做讨论,欢迎高人指点。

      分析:此题的难点在于表B中的ID复杂表示,其实这样有悖于数据库的设计原则,理应表A和表B的ID一一对应。既然是题,我们只能从当前的条件入手了,攻破难点的关键在于判断A中ID在B中ID出现与否,如果出现那么如何统计出现的次数。判断出现与否需要用到函数CHARINDEX

     解决方案如下:

 1 --创建测试数据
 2 WITH TA
 3 AS
 4 (SELECT 1,2 AS ID,job1 AS task
 5 UNION SELECT 1,2,3,job3
 6 UNION SELECT 2,3,job2
 7 UNION SELECT 3,4,5,job4)
 8 ,TB AS  
 9 (SELECT 1 AS ID,张三 as name
10 UNION SELECT 2,王二
11 UNION SELECT 3,李四
12 UNION SELECT 4,李明
13 UNION SELECT 5,王五)
14 
15 SELECT B.ID,B.name,COUNT(1) AS TASKS
16  FROM TA A,TB B
17   WHERE CHARINDEX(B.ID,A.ID)>0
18   GROUP BY B.ID,B.name
19   order by B.ID 

    题目三:原题参见博客:http://www.cnblogs.com/Lumia1020/p/4571301.html

      如下表City所示,code为行政区域码(六位数字,前两代表省级,中间两位代表市级,最后两位代表县级,不考虑xx00xx情况),city为城市名称,CCode为该城市所属的省级或者市级行政区域码。

技术分享

 

       现需求如下结果:

       技术分享

     分析:分析表city,code的含义十分明显,所需要的结果也很明显,如果是省就是显示省份;是市则显示为所属省级+市级;是县级则显示为所属省级+所属市级+县级。貌似可以用题目一分析中提到的SQL条件语句实现,但是转念一想,还是有差别,这里需要先判断city属于省级?市级?县级?然后在对应起来的,这样还得有参照表,复杂了。回到结果表中来进行分析,其实判定city属于省市县的问题并不难,code的含义已经说明了,只要转换表述:在表City中,当code的后四位为“0000”时,肯定是省级;当code的后两位为“00”,并且后四位不为“0000”时,肯定是市级;当code后两位不为“00”时,为县级。这样省市县的判定就一目了然了,然后,根据市级编码追朔所属的省级,并得出所属省级+市级,县级追朔所属的市级,得出所属省级+所属市级+所属县级,通过运用这种简单的递归思想,解决方案便跃然纸上了。

     解决方案如下:

 1 --测试数据
 2 with ta as
 3 (select 110000 as code, 北京市 city, 110000 Ccode
 4 union
 5 select N110200, N西城区, N110200
 6 union
 7 select N110300, N崇文区, N110300
 8 union
 9 select N430000, N湖南省, N430000
10 union
11 select N430100, N长沙市, N430100
12 union
13 select N430101, N望城县, N430100)
14 
15 select * into City from ta
16 
17 select * from City;
18 
19 --解决方案
20 with ta
21 as(
22 --省级
23 select code,city,Ccode,city content from City where right(code,4)=0000),
24 tb as(
25 --市级
26 select b.code,b.city,b.Ccode,a.city+,+b.city as content from ta a,City b where left(a.Ccode,2)=left(b.Ccode,2)
27 and right(b.code,2)=00 and right(b.code,4)<>0000),
28 tc as(
29 select c.code,c.city,c.Ccode,b.content+,+c.city content from tb b,City c where left(b.Ccode,4)=left(c.Ccode,4)
30 and right(c.code,2)<>00)
31 select * from ta
32 union
33 select * from tb
34 union
35 select * from tc

       通过上述几道小题,常思常新,温故了SQL的部分知识,当然方法很多,变式很多,如题目二统计表B中每个Task的人数等。不足之处,欢迎各位指点!

 

关于SQL的几道小题详解

标签:

原文地址:http://www.cnblogs.com/zhangbc/p/4576101.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!