当需要对查询到的结果进行比较复杂的处理的时候,可以借助联合查询、子查询等得到期望的结果。下面列举一个具体的经典试题,希望对读者有所启发。
1.题目要求:
表 NBA 记录了TEAM
夺冠球队的名称及年份:
TEAM YEAR
--------------------------------------------------
活塞 1990
公牛 1991
公牛 1992
公牛 1993
火箭 1994
火箭 1995
公牛 1996
公牛 1997
公牛 1998
马刺 1999
湖人 2000
湖人 2001
湖人 2002
马刺 2003
活塞 2004
马刺 2005
热火 2006
马刺 2007
凯尔特人 2008
湖人 2009
湖人 2010
请写出一条 SQL 语句,查询出在此期间连续获得冠军的有哪些,其连续的年份的起止时间是多少,结果如下:
TEAM BEGIN END
-------------------------------------------
公牛 1991 1993
火箭 1994 1995
公牛 1996 1998
湖人 2000 2002
湖人 2009 2010
2.题目分析:
这道题目可以分解为两步:
第一步:找出所有连续获得冠军的球队
第二
步
:计算
连续获得冠军的球队的起止年份
3.代码实现
《1》建表并插入一些数据:
-- Create table create table NBA ( team NUMBER, year NUMBER ) tablespace USERS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K minextents 1 maxextents unlimited );
为了方便起见,这里仅用数字代替球队,随意插入一些测试数据:
《2》我们观察数据发现,如果连续获的一年以上的冠军,那么前一年出现的球队下一年依然会出现,
即:team(year)=team(year+1);
例如下面记录片段 :
活塞 1990
公牛 1991
公牛 1992
公牛 1993
火箭 1994
具体的 SQL 语句为:
select n2.team,n2.year from (select * from nba) n1 join (select * from nba) n2 on n1.team=n2.team where n1.year=n2.year+1
执行结果为:
《3》最后,将上面的查询结果作为子查询,对数据进行处理,因为得冠军最后一年的下面一年不是冠军,
所以结束年份为
max(year)+1:
select max(nn.team) team,min(nn.year) BeginYear,max(nn.year)+1 EndYear from (select n2.team,n2.year from (select * from nba) n1 join (select * from nba) n2 on n1.team=n2.team where n1.year=n2.year+1) nn group by (nn.year-rownum) order by BeginYear ;
下面是最终的执行结果:
4.总结思考
面对类似的面试题目或者问题,虽然涉及的知识点(子查询、连接查询等)不是很多,但是因为有一些数据的转化和查询的嵌套,可能会造成一些心理素质较差的读者手足无措。因此,面对类似的复杂问题,要学会使用“拆分法”进行分解,一步步地解决问题。
祝你成功!