基于顺序的oracle表分组

Posted

技术标签:

【中文标题】基于顺序的oracle表分组【英文标题】:oracle table grouping based on order 【发布时间】:2020-04-03 08:48:59 【问题描述】:

我有一个 oracle 表,其中 ref_id 是标志字段是数据类型,ORN 是每个 ref_id 中数据的顺序:

ref_id   data    ORN   flag
  1       100     0     0
  1       200     1     0
  1       300     2     0
  1       400     3     0
  1       110     0     1
  1       210     1     1
  1       150     0     2
  1       250     1     2
  1       350     2     2
  1       450     3     2
  2       500     0     0
  2       600     1     0
  2       700     2     0
  2       800     3     0
  2       120     0     1
  2       220     1     1
  2       320     1     1
  2       420     1     1
  2       170     0     2
  2       270     1     2
  2       370     2     2
  2       470     3     2

我需要将数据分组如下:

标志 0 中的最后一个数据与标志 1 中的第一个数据 标志 1 中的每个数据与下一个数据(标志 1 中的数据数为 不修复) 标志 1 中的最后一个数据与标志 2 中的第一个数据

所以新表将是这样的:

ref_id    data_1    data_2
  1        400       110
  1        110       210
  1        210       150
  2        800       120
  2        120       220
  2        220       320
  2        320       420
  2        420       170

任何提示如何在不使用循环的情况下完成此操作?

【问题讨论】:

【参考方案1】:

你可以使用窗口函数:

select ref_id, data data_1, lead_data data2
from (
    select
        t.*,
        lead(flag) over(partition by ref_id order by flag, orn) lead_flag,
        lead(data) over(partition by ref_id order by flag, orn) lead_data
    from mytable t
) t
where 
    flag = 0 and lead_flag = 1
    or (flag = 1 and lead_flag = 1)
    or (flag = 1 and lead_flag = 2)
order by ref_id, flag, orn

Demo on DB Fiddle

REF_ID |数据_1 |数据2 -----: | -----: | ----: 1 | 400 | 110 1 | 110 | 210 1 | 210 | 150 2 | 800 | 120 2 | 120 | 220 2 | 220 | 320 2 | 320 | 420 2 | 420 | 170

请注意,对于这个数据集,where 子句可以简化为:

where 1 in (flag, lead_flag)

【讨论】:

以上是关于基于顺序的oracle表分组的主要内容,如果未能解决你的问题,请参考以下文章

[Oracle]Oracle良性SQL建议

oracle查询优化

Oracle初级优化sql

Oracle 性能优化

Oracle 性能优化

ORACLE 中 SQL语句优化