查找表中每个 ID 的最大连续年份(Oracle SQL)

Posted

技术标签:

【中文标题】查找表中每个 ID 的最大连续年份(Oracle SQL)【英文标题】:Find the maximum consecutive years for each ID's in a table(Oracle SQL) 【发布时间】:2013-05-31 17:14:36 【问题描述】:

我正在尝试解决如何在一系列记录中找到连续年份的最大计数的问题。在以下示例中:

身份证年 1 1993 1 1994 1 1995 1 1995 1 2001 1 2002 2 1993 2 1995 2 1996 2 1996 2 1998 2 1999 2 2000 2 2001 2 2001

我的结果集应该是这样的

身份证号码 1 3 2 4

我必须在 oracle SQL 中编写代码。

【问题讨论】:

请使用 SQL Fiddle。 这听起来像是递归 CTE 的工作,其中每次迭代都将一行与前一年的行匹配。不过,不确定这在 Oracle 中的效果如何,所以我将其作为评论留下,可能有助于其他人的答案。 【参考方案1】:

这将产生您想要的结果:

select
  id,
  ayear,
  byear,
  yeardiff
from
(
  select
    a.id,
    a.year ayear,
    b.year byear,
    (b.year - a.year)+1 yeardiff,
    dense_rank() over (partition by a.id order by (b.year - a.year) desc) rank
  from
    years a
    join years b on a.id = b.id 
        and b.year > a.year
  where
    b.year - a.year = 
      (select count(*)-1
         from years a1
        where a.id = a1.id
             and a1.year between a.year and b.year)
)
where
  rank = 1

EDIT 更新为显示最长延伸的开始/结束年份。

SQLFiddle

【讨论】:

这是一个了不起的回应..虽然我仍然需要理解代码(我是 sql 新手)..但我真的很感谢你在这方面的时间。非常感谢乔。 嗨,乔,我的实际数据集中有重复的行。在这种情况下,这段代码似乎不起作用。您能否帮助我修改代码的修改版本,该版本也可以解决重复行..(注意:我修改了主要问题中的测试数据) 当然,只需将:“(选择计数(*)-1”更改为“(选择计数(不同年份)-1”) 没问题。我更新了上面的原始答案以反映更改。 嗨乔,有没有办法我也可以显示用于计算此查询中年份差异的年份?提前致谢。 -AVG【参考方案2】:

试试:

with cte as
(select t.id, t.year, d.d, row_number() over (partition by t.id, d.d 
                                              order by t.year) rn
 from (select -1 d from dual union all select 1 d from dual) d
 cross join my_table t 
 where not exists
       (select null
        from my_table o
        where t.id = o.id and t.year = o.year-d.d) )
select s.id, max(e.year-s.year)+1 year_count
from cte s
join cte e on s.id = e.id and s.rn = e.rn and e.d=1
where s.d=-1
group by s.id

SQLFiddle here.

【讨论】:

嗨,我正在寻找一个没有 CTE 的解决方案..很可能使用标志。这是因为我正在尝试使用此 SQL 构建 SAP Web 智能报告。带有标志的解决方案对我非常有帮助 但是非常感谢您的快速响应 MARK。 @user2283660:为什么使用 SAP Web 智能报告会排除 CTE? “旗帜”是什么意思? 我遇到了一个解决方案..其中标志用于实现所需的结果..但不幸的是它是用 SQL Server 编写的,不适合 oracle。来源:sqlservercentral.com/Forums/Topic10547-8-1.aspx?Update=1。对不起,如果我让你感到困惑。谢谢 @user2283660:CTE 中的d 列的作用与链接示例中的flag 列类似。您还没有解释为什么不能在 SAP 网络智能报告中使用 CTE。【参考方案3】:

与 t1 作为 ( 选择 ID, 年, 领先(年)超过(按年按 id 顺序分区)作为 nxt_yr 从树 ), t2 为 ( 选择 ID, 年, nxt_yr, nxt_yr - 年份作为差异 从 t1 ), t3 为 (选择 ID, 年, nxt_yr, 差异, lag(diff) over(partition by id order by year) as diff_lag, 领先(差异)超过(按年按 id 顺序分区)作为 diff_lead 从 t2 ) 选择 id, sum(diff) + 1 从 t3 其中 ((diff = 1) 和 (diff_lag = 1)) 或 ((diff = 1) 和 (diff_lead = 1)) 按 id 分组

【讨论】:

欢迎来到 Stack Overflow。您可能希望为您的答案使用更好的格式,并解释为什么这会回答给定的问题。

以上是关于查找表中每个 ID 的最大连续年份(Oracle SQL)的主要内容,如果未能解决你的问题,请参考以下文章

从查找表中获取每个类型和每个日期的最大 ID

ORACLE SQL 查找每个分组的最大日期行

从带有last.fm乱码的mysql表中查找给定年份的前100名[重复]

oracle用exists查询一张表中不连续的id值

查找列的最大值,按不同表中的列分组

查找连续周人员出现在表中