PLSQL查询分类组中的每一组最大值的一条记录

//根据object_id分组,每组中,取survey_id最大,按survey_id排序为desc。
//取survey_id最小,按survey_id排序为asc
//rank() 或者 row_number()
select * from (select rank() over(partition by a.object_id order by a.survey_id desc
) rn,a.*
from (select * from T_Icm_Clm_Mt_Survey) a)
where rn = 1

去掉rn = 1的条件

[img]http://dl2.iteye.com/upload/attachment/0119/8394/20016ac6-9438-38a9-8d11-2f7e18f9aba1.png[/img]

就是根据排序,然后通过rn = 1来获得所需的最大值,最小值


OVER(PARTITION BY)函数介绍
over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
over(partition by deptno)按照部门分区


over(partition by deptno order by salary)

2:开窗的窗口范围:
over(order by salary range between 5 preceding and 5 following):
窗口范围为当前行数据幅度减5加5后的范围内的。
over(order by salary rows between 5 preceding and 5 following):
窗口范围为当前行前后各移动5行。

与over函数结合的几个函数介绍

row_number()over()、rank()over()和dense_rank()over()函数的使用
1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,
row_number()只返回一个结果;

2.rank()和dense_rank()可以将所有的都查找出来:
如上可以看到采用rank可以将并列第一名的都查找出来;
rank()和dense_rank()区别:
--rank()是跳跃排序,有两个第二名时接下来就是第四名;
--dense_rank()l是连续排序,有两个第二名时仍然跟着第三名

详细请看博文 [url]http://www.cnblogs.com/lanzi/archive/2010/10/26/1861338.html[/url]
<think>嗯,用户问的是PL/SQL中如何删除全字段重复相同的数据。首先,我需要确认用户的需求:他们想要删除表中所有字段都完全相同的重复记录,保留其中一条。可能的情况是,用户的数据表中存在多条所有列值都相同的记录,他们希望清理这些冗余数据。 接下来,我得考虑不同的方法来解决这个问题。常见的方法有用ROWID、ROW_NUMBER()窗口函数,或者创建临时表。我需要逐一分析这些方法的步骤和适用场景,并确保语法正确。 首先,ROWID的方法。Oracle中每个表都有ROWID伪列,唯一标识一行。通过按所有字段分组,找到最小(或最大)ROWID的记录,然后删除其他ROWID的记录。这里需要注意的是,如果表有大量数据,直接DELETE可能会影响性能,可能需要分批次处理。 然后是ROW_NUMBER()函数。给每重复数据分配序号,然后删除序号大于1的记录。这种方法在子查询中可能需要使用临时表或CTE,因为在Oracle中不能直接删除带有ROW_NUMBER()的查询结果。可能需要用子查询或者内联视图。 第三种方法是创建临时表,将去重后的数据插入临时表,然后替换原表。这种方法适用于数据量较大的情况,因为TRUNCATE和INSERT操作通常比DELETE更快。但需要确保有足够的权限和空间,并且在操作期间表会被锁定,可能影响其他操作。 同时,需要考虑事务处理,比如在删除前备份数据,使用COMMIT或ROLLBACK。还要提醒用户谨慎操作,避免数据丢失。此外,如果表有主键或唯一索引,可能不会存在全字段重复的情况,但用户的问题中假设没有这样的约束。 可能的误区是用户可能没有正确识别所有字段,或者在分组时遗漏字段,导致误删或未完全删除。需要强调GROUP BY必须包含所有字段。另外,性能问题也需要提及,特别是当数据量很大时,可能需要分批处理或选择更高效的方法。 最后,要确保给出的示例代码正确,比如使用正确的语法,别名,子查询结构。比如在ROWID方法中,正确的DELETE语句应该子查询找到要保留的ROWID,然后删除不在其中的记录。而在窗口函数方法中,可能需要使用子查询或临时表来避免直接引用分析函数的结果。</think>在PL/SQL中删除全字段重复的数据,可以通过以下步骤实现: ### 一、理解重复数据特征 全字段重复指:所有列的值都相同的记录,例如: $$ \begin{array}{|c|c|c|} \hline id & name & age \\ \hline 1 & Amy & 20 \\ 1 & Amy & 20 \\ \hline \end{array} $$ ### 二、常用删除方法 #### 方法1:使用ROWID + GROUP BY ```sql DELETE FROM your_table WHERE rowid NOT IN ( SELECT MIN(rowid) -- 也可用MAX(rowid) FROM your_table GROUP BY column1, column2, ..., columnN -- 所有字段都要列出 ); ``` **原理**:通过分组找到每重复数据中保留的ROWID,删除其他记录 #### 方法2:使用ROW_NUMBER()窗口函数 ```sql DELETE FROM your_table WHERE (column1, column2, ..., columnN, rowid) IN ( SELECT column1, column2, ..., columnN, rowid FROM ( SELECT t.*, ROW_NUMBER() OVER ( PARTITION BY column1, column2, ..., columnN ORDER BY rowid ) rn FROM your_table t ) WHERE rn > 1 ); ``` **优势**:更直观控制保留策略(保留第一条/最后一条) #### 方法3:创建临时表 ```sql CREATE TABLE temp_table AS SELECT DISTINCT * FROM your_table; TRUNCATE TABLE your_table; INSERT INTO your_table SELECT * FROM temp_table; DROP TABLE temp_table; ``` **适用场景**:数据量较大时效率更高 ### 三、注意事项 1. **事务控制**:先执行`BEGIN`开启事务,确认结果后再`COMMIT` 2. **字段完整性**:GROUP BY必须包含所有字段 3. **备份数据**:操作前建议执行 ```sql CREATE TABLE your_table_bkp AS SELECT * FROM your_table; ``` 4. **性能优化**:对大数据量表建议添加`WHERE rownum <= N`分批删除 ### 四、验证示例 原始数据: $$ \begin{array}{|c|c|c|} \hline id & product & qty \\ \hline 1001 & Pen & 50 \\ 1001 & Pen & 50 \\ 1002 & Book & 30 \\ \hline \end{array} $$ 执行方法1后保留: $$ \begin{array}{|c|c|c|} \hline 1001 & Pen & 50 \\ 1002 & Book & 30 \\ \hline \end{array} $$ 建议根据实际表结构和数据量选择最合适的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值