各位用户为了找寻关于关于SQL的几道小题详解(sql进阶)的资料费劲了很多周折。这里教程网为您整理了关于关于SQL的几道小题详解(sql进阶)的相关资料,仅供查阅,以下为您介绍关于关于SQL的几道小题详解(sql进阶)的详细内容
当我们拿到题目的时候,并不是急于作答,那样会得不偿失的,而是分析思路,采用什么方法,达到什么目的,还要思考有没有简单的方法或者通用的方法等等,这样才会达到以一当十的效果,这样的惯性思维其实早在我们度高中的时候就被领教了,所谓“万变不离其宗”吧。以下各题来自日常所见,或QQ群,或面试题,或博客园。
题目一:如下表所示,现需要按照收款员统计收款和退款合计金额。
实现结果需如下显示:
分析:想要的结果(记为表B)和源数据(记为表A)相比,有共同的列(收款员),不同的是表A的金额根据标记和收款员分成了两列,所以这个需求可以用语言表述一下:首先根据收款员分组(group by),然后当标记为“收”时,金额计入收款合计(sum);当标记为“退”时,金额计入退款合计(sum)。当……时……,这不就是SQL的条件判断嘛?盘点SQL的条件语句不多,if……else……和case……when……then……else……end。这样问题就迎刃而解了。
解决方案如下:
? 1 2 3 4 5 6 7 8 9 10 11 12with
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。
解决方案如下:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19--创建测试数据
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.zzvips.com/article/57305.html
如下表City所示,code为行政区域码(六位数字,前两代表省级,中间两位代表市级,最后两位代表县级,不考虑xx00xx情况),city为城市名称,CCode为该城市所属的省级或者市级行政区域码。
现需求如下结果:
分析:分析表city,code的含义十分明显,所需要的结果也很明显,如果是省就是显示省份;是市则显示为所属省级+市级;是县级则显示为所属省级+所属市级+县级。貌似可以用题目一分析中提到的SQL条件语句实现,但是转念一想,还是有差别,这里需要先判断city属于省级?市级?县级?然后在对应起来的,这样还得有参照表,复杂了。回到结果表中来进行分析,其实判定city属于省市县的问题并不难,code的含义已经说明了,只要转换表述:在表City中,当code的后四位为“0000”时,肯定是省级;当code的后两位为“00”,并且后四位不为“0000”时,肯定是市级;当code后两位不为“00”时,为县级。这样省市县的判定就一目了然了,然后,根据市级编码追朔所属的省级,并得出所属省级+市级,县级追朔所属的市级,得出所属省级+所属市级+所属县级,通过运用这种简单的递归思想,解决方案便跃然纸上了。
解决方案如下:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35--测试数据
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的部分知识,当然方法很多,变式很多,如题目二统计表B中每个Task的人数等。不足之处,欢迎各位指点!