SQL的小题详解

2019-10-17 09:00:31来源:爱站网 阅读 ()

新老客户大回馈,云服务器低至5折

其实当我们拿到题目的时候不要急于作答,而是要仔细分析思路,还要思考有没有简单的方法或者通用的方法等,那么今天小编就为介绍关于SQL的小题详解,大家一起来学习吧。

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

实现结果需如下显示:

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

解决方案如下:

with ta as
(select '收' as 标记,'100' as 收款员,150 as 金额
 union
 select '收','100',375
 union
 select '退','100',78
 union select '收','200',74
)

select 收款员,sum(case when 标记='收' then 金额 else 0 end) as 收款合计,
 sum(case when 标记='退' then 金额 else 0 end) as 退款合计 from ta
 group by 收款员

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

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

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

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

解决方案如下:

--创建测试数据
WITH TA
AS
(SELECT '1,2' AS ID,'job1' AS task
UNION SELECT '1,2,3','job3'
UNION SELECT '2,3','job2'
UNION SELECT '3,4,5','job4')
,TB AS 
(SELECT '1' AS ID,'张三' as name
UNION SELECT '2','王二'
UNION SELECT '3','李四'
UNION SELECT '4','李明'
UNION SELECT '5','王五')

SELECT B.ID,B.name,COUNT(1) AS TASKS
 FROM TA A,TB B
 WHERE CHARINDEX(B.ID,A.ID)>0
 GROUP BY B.ID,B.name
 order by B.ID

题目三:原题参见这篇文章:http://www.aizhan.com/article/67885.htm

?

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

?

现需求如下结果:

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

解决方案如下:

--测试数据
with ta as
(select '110000' as code, '北京市' city, '110000' Ccode
union
select N'110200', N'西城区', N'110200'
union
select N'110300', N'崇文区', N'110300'
union
select N'430000', N'湖南省', N'430000'
union
select N'430100', N'长沙市', N'430100'
union
select N'430101', N'望城县', N'430100')

select * into City from ta

select * from City;

--解决方案
with ta
as(
--省级
select code,city,Ccode,city content from City where right(code,4)='0000'),
tb as(
--市级
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)
and right(b.code,2)='00' and right(b.code,4)<>'0000'),
tc as(
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)
and right(c.code,2)<>'00')
select * from ta
union
select * from tb
union
select * from tc

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


原文链接:https://js.aizhan.com/data/mssql/9533.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:关于SQL Server自旋锁的介绍

下一篇:SQLServe如何删除重复行