sql语句查找记录中的连续数据
2016-12-19 20:20
197 查看
用一条sql语句查找记录中的连续数据
背景
oracle作业有一道题:用一条语句查出连续获得冠军的队伍,和其连续获胜的开始年B、结束年E
数据如下(表名NBA):
TEAM | Y |
---|---|
活塞 | 1990 |
公牛 | 1991 |
公牛 | 1992 |
公牛 | 1993 |
火箭 | 1994 |
火箭 | 1995 |
公牛 | 1996 |
公牛 | 1997 |
公牛 | 1998 |
马刺 | 1999 |
湖人 | 2000 |
湖人 | 2001 |
湖人 | 2002 |
马刺 | 2003 |
活塞 | 2004 |
马刺 | 2005 |
热火 | 2006 |
马刺 | 2007 |
凯尔特人 | 2008 |
湖人 | 2009 |
湖人 | 20010 |
TEAM | B | E |
---|---|---|
公牛 | 1991 | 1993 |
火箭 | 1994 | 1995 |
公牛 | 1996 | 1998 |
湖人 | 2000 | 2002 |
湖人 | 2009 | 2010 |
思路
既然要求一条语句,就不能用PL/SQL了考虑先把TEAM和连续获胜的Y选出来,至于B和E,MIN和MAX就能选出来。
那么问题来了,怎么把TEAM和连续获胜的Y选出来
由于oracle内置表中有scott.emp这张表,就用这张表试刀,省得再创建一张表了。
以下sql语句的作用是选出scott.emp表中,同一个deptno,间隔为1150的连续的sal。
SELECT * FROM scott.emp my_table2 -- 遍历scott.emp每一条记录,从中挑出满足以下条件的记录 WHERE exists( -- 每个部门分一个组,若该部门内有my_table2.sal + 1150,说明my_table2.sal再间隔1150即有一条满足的记录 -- 因此my_table2.sal所在的记录要被选入 SELECT my_table3.DEPTNO,my_table3.sal FROM scott.emp my_table3 GROUP BY my_table3.DEPTNO,my_table3.sal HAVING my_table3.sal = my_table2.sal + 1150 AND my_table3.DEPTNO = my_table2.DEPTNO ) -- 扫描结束,每个部门的最后一条合法sal都没有被纳入,因此加个union UNION SELECT * FROM SCOTT.EMP WHERE SCOTT.EMP.SAL IN ( -- 挑出每一个部门里被遗漏最后一个的合法sal -- 其实就是上面select的结果每一组的最大值+1150,所以from和where是一模一样的 SELECT max(SAL) + 1150 FROM scott.emp my_table2 WHERE exists( SELECT my_table3.DEPTNO,my_table3.sal FROM scott.emp my_table3 GROUP BY my_table3.DEPTNO,my_table3.sal HAVING my_table3.sal = my_table2.sal + 1150 AND my_table3.DEPTNO = my_table2.DEPTNO ) GROUP BY my_table2.DEPTNO )
结果集如图
解决办法
上面已经把最重要的resolve了。回到开始的题目,使用以下sql语句应该就能搞定:SELECT TEAM,min(Y) B,max(Y) E FROM ( SELECT * FROM NBA my_table2 WHERE exists( SELECT my_table3.TEAM,my_table3.Y FROM NBA my_table3 GROUP BY my_table3.TEAM,my_table3.Y HAVING my_table3.Y = my_table2.Y + 1 AND my_table3.TEAM = my_table2.TEAM ) UNION SELECT * FROM NBA WHERE NBA.Y IN ( SELECT max(Y) + 1 FROM NBA my_table2 WHERE exists( SELECT my_table3.TEAM,my_table3.Y FROM NBA my_table3 GROUP BY my_table3.TEAM,my_table3.Y HAVING my_table3.Y = my_table2.Y + 1 AND my_table3.TEAM = my_table2.TEAM ) GROUP BY my_table2.TEAM ) ) my_table1 GROUP BY TEAM
吐槽
目前为止遇到过最烧脑的一个sql,想了一天,智商需要充值。相关文章推荐
- MySQL字符串函数substring:字符串截取
- MySQL基础小知识
- mongo 图形客户端解决无法添加拷贝数据库问题
- mongodb+pycharm使用报错,无法往mongodb存文件
- 利用ADO让普通人用excel读取oracle数据库表的通用办法
- 颤抖吧,骚年们,2016年末最牛逼的sql语句
- SQL查询语句精华使用简要
- PL/SQL远程连接数据库的操作办法
- x86 架构下安装oracle RAC 要注意到点
- GreenDao使用详解
- 由于网卡单队列导致的CPU高
- 数据库中的索引
- 用Jmeter对数据库执行压力测试
- sqlserver insert--缓存 爬坑
- 数据库 权限设计 角色 用户组
- MySQL主从复制的原理及配置方法(比较详细)
- mysql主从复制配置
- 高性能Mysql主从架构的复制原理及配置详解
- ubuntu14.04.1上安装mongodb3.4
- Auzre微软云Redis后台StackExchange.Redis使用KeySpaceNotification实现缓存过期前操作/处理一些事件