背景

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


参考链接:https://blog.csdn.net/qq_24872197/article/details/53747942

发表评论

邮箱地址不会被公开。 必填项已用*标注