首先带上原文的链接:http://www.itpub.net/thread-1873736-1-1.html。
有数据如下:
with tmp_t as( select 1 as id ,'aaa' as v_name from dual union all select 2 as id ,'aaa' as v_name from dual union all select 3 as id ,'aaa' as v_name from dual union all select 5 as id ,'aaa' as v_name from dual union all select 6 as id ,'bbb' as v_name from dual union all select 7 as id ,'bbb' as v_name from dual union all select 8 as id ,'ccc' as v_name from dual union all select 9 as id ,'zzz' as v_name from dual union all select 11 as id ,'zzz' as v_name from dual union all select 13 as id ,'zzz' as v_name from dual union all select 14 as id ,'zzz' as v_name from dual )
求v_name的连续区间。
期望的结果:
容易理解的写法:
select v_name, decode(count(*), 1, to_char(min(id)), min(id) || '-' || max(id)) b from (select id, v_name, max(rn) over(partition by v_name order by id) rn from (select id, v_name, decode(id - lag(id) over(partition by v_name order by id), 1, 0, id) rn from tmp_t)) group by v_name, rn order by v_name, rn;
简单的写法:
select v_name, decode(to_char(mi),to_char(ma) ,to_char(ma),to_char(mi) || '-' || to_char(ma)) b from (select v_name, min(id) mi, max(id) ma from (select t.* from tmp_t t order by t.v_name, t.id) group by v_name, id - rownum order by v_name);
简洁的写法:
--连续ID减行号的差值一定是相同的 select v_name, decode(count(*), 1, to_char(min(id)), min(id) || '-' || max(id)) b from (select t.*, id - row_number() over(partition by v_name order by id) gp from tmp_t t) group by v_name, gp order by v_name
求连续值范围一般都是先求差值,在按差值分组,如下所示:
with tmp_t as( select to_date('201401','yyyy-mm') as v_month,100 as v_value from dual union all select to_date('201402','yyyy-mm'),100 from dual union all select to_date('201404','yyyy-mm'),100 from dual union all select to_date('201405','yyyy-mm'),300 from dual union all select to_date('201406','yyyy-mm'),100 from dual union all select to_date('201311','yyyy-mm'),110 from dual union all select to_date('201310','yyyy-mm'),110 from dual union all select to_date('201407','yyyy-mm'),100 from dual ) select v_value,decode(to_char(min(v_month), 'yyyymm'), to_char(max(v_month), 'yyyymm'), to_char(max(v_month), 'yyyymm'), to_char(min(v_month), 'yyyymm') || '-' || to_char(max(v_month), 'yyyymm')) v_range from (select v_month, v_value, to_number(to_char(add_months(v_month, -1 * row_number() over(partition by v_value order by v_month)), 'yyyymm')) diff from tmp_t) group by diff, v_value order by 1;
结果为:
全文完。
相关推荐
序列在Oracle中是一个预定义的对象,可以生成一个有序的数字流,这些数字可以是连续的,也可以有一定的间隔。序列的生成是线程安全的,意味着多个用户同时请求序列时,每个用户都会得到一个唯一的值,而不会出现冲突...
### Oracle连续重复行去重详解 在Oracle数据库中,处理连续重复行的去重操作是一项常见但又具有一定挑战性的任务。特别是当需要合并特定条件下连续出现的记录时,这一过程会更加复杂。本文将深入探讨如何实现...
Oracle 10g 中用 FORALL 处理非连续数组 Oracle 10g 中的 FORALL 语句可以处理非连续数组,这种能力在以前的版本中是不存在的。在 Oracle 10g 中,FORALL 语句可以使用 INDICES OF 和 VALUES OF 子句来处理非连续...
当范围被分配或释放时,Oracle 会更新这些位图值来反映块的新状态,而这种更新不会产生回滚信息,因为它不涉及数据字典表的更新(除了表空间配额信息),这与默认的字典管理方法形成鲜明对比。 ### 2. LMT 表空间...
- `dayofweek`: 星期,值范围0-6,星期日值为0 - `command`: 执行的命令 #### 三、恢复方案设计 ##### 1. 数据库恢复流程 当需要恢复数据库时,可以按照以下步骤进行操作: - **确认备份文件完整性**:检查...
序列是一种用于生成连续整数值的对象,它可以在创建表时或之后定义,并被用来为表中的特定字段提供唯一的递增值。为了在插入数据时能够自动获取自增ID,首先需要创建一个序列对象。 ##### 创建序列 根据给定的部分...
- **范围分区**:根据字段值的范围进行分区,例如,根据日期或序列号。例如,创建物料交易表时,可以根据交易ID或交易日期进行范围分区,确保相同范围的数据存储在同一分区。 - **Hash分区**(散列分区):基于...
- **范围分区**:根据字段值的范围将数据分配到不同的分区,如日期范围分区。 - **列表分区**:根据预定义的列表值将数据分配到分区。 - **散列分区**:基于散列函数将数据均匀分布到多个分区,实现负载均衡。 -...
数据库碎片是影响数据库性能的一大因素,碎片的产生是由于表空间中的自由空间被分割成多个小的自由范围块,导致数据存储不连续、寻找数据困难,从而影响数据库性能。 标签:Oracle、数据库碎片 一、碎片的产生 ...
2. **扩展范围碎片(Extent Fragmentation)**:由于频繁的插入和删除操作,导致同一表的数据分布在多个不连续的扩展范围内。 3. **块碎片(Block Fragmentation)**:指的是数据块内部的未使用空间的分散程度。 #### ...
- **数据的约束条件:** 规定了数据的有效值范围和完整性规则。 #### 三、Oracle数据库中的重要组件 - **数据库文件:** - 控制文件:记录数据库的物理结构相关信息。 - 数据文件:存储实际数据的文件。 - ...
范围分区通常基于连续的数值或日期范围,例如年份。这种方式适用于记录有明确时间戳的数据,如订单、交易记录等。以下是一个创建按年分区表的示例脚本: ```sql CREATE TABLE sales ( sale_id NUMBER PRIMARY KEY,...
在Oracle中,序列(SEQUENCE)是一种特殊的数据库对象,用于生成连续的数值。通过序列可以在插入记录时,自动为新记录生成唯一的标识符,例如: ```sql UPDATE zl_spzlbxxy SET sccjid = seq_zl_spjgtxb_jiagid....
Oracle分区表中的Hash分区是一种基于哈希算法的分区策略,适用于处理无法清晰定义分区范围的大型数据表。这种分区方式通过计算分区键的哈希值来决定数据存储在哪个分区,以此达到数据分散和负载均衡的目的。Hash分区...
范围分区通常用于根据连续的数值(如日期)将数据分段;列表分区则适用于预定义的一组值;哈希分区通过计算散列函数将数据分布到各个分区;而复合分区则结合了两种或更多分区方法。创建分区表时,需要指定分区键、...
Range分区是基于数值或日期范围进行数据分割,通常适用于连续的、有序的数据。例如,在上述的例子中,`customer`表按照`area_code`字段的数值范围进行分区,每个分区对应特定的电话区号。这样的设计有助于快速定位和...
3. ROW_NUMBER() 函数:为每一行提供唯一的数字,不论值是否相同,连续分配。 4. AVG() 分析函数:计算一组行的平均值,可以配合OVER()子句指定计算范围。 5. SUM() 分析函数:对一组行进行求和,同样可以使用OVER...
这种方法不仅能够有效减少因重新搭建DataGuard所消耗的时间和资源,还能最大限度地保证业务的连续性。下面将详细介绍这一过程中的具体步骤和技术要点。 #### 三、增量恢复的主要步骤 ##### 1. 在备用库上查找当前 ...
AND ...))可以计算连续行的累加值,而移动平均数则是对指定窗口内的平均值进行计算。 5. RATIO_TO_REPORT 这个函数返回当前行值占总和的比例,可以用于快速计算每个分组在整体中的占比。 6. FIRST_VALUE和LAST_...
理想情况下,单个文件表空间的FSFI值为100,随着范围数量的增加和最大范围尺寸的减小,FSFI值逐渐降低。 通过编写SQL脚本来计算FSFI值可以帮助我们了解不同表空间的碎片情况。例如,以下SQL脚本用于计算FSFI值: ``...