我是oracle数据库的新手,可以帮助我理解这个查询。此查询消除了表中的重复项。
DELETE FROM table_name A
WHERE ROWID > (SELECT min(rowid)
FROM table_name B
WHERE A.key_values = B.key_values);
欢迎任何改进查询的建议。
编辑:不,这不是功课,我不明白的是,子查询做了什么以及ROWID > On
子查询做了什么?
答案 0 :(得分:5)
剖析实际的机制:
DELETE FROM table_name A
这是从名为“table_name”的表中删除记录的标准查询。在这里,它被别名为“A”,在子查询中引用。
WHERE ROWID >
这为删除条件设置了一个条件,这样对于遇到的每一行,ROWID必须使用大于...的条件。
(SELECT min(rowid)
FROM table_name B
WHERE A.key_values = B.key_values)
这是一个与主DELETE语句相关的子查询。它使用外部查询中的值A.key_values
。因此,给定来自DELETE语句的记录,它将运行此子查询以查找同一表中的所有记录的最小rowid(内部记录ID)(现在为别名为B),其具有相同的key_values
值。
所以,把它放在一起,说你有这些行
rowid | key_values
======= ============
1 A
2 B
3 B
4 C
5 A
6 B
子查询表明,基于具有相同key_values
的所有记录的每条记录的min(rowid)是:
rowid | key_values | min(rowid)
======= ============ ===========
1 A 1
2 B 2
3 B 2 **
4 C 4
5 A 1 **
6 B 2 **
对于标有 **
的记录,条件
WHERE ROWID > { subquery }
变为真,并将其删除。
此答案之前曾说过ROWID因插入顺序而增加。这是非常不真实的。事实是rowid is just a file.block.slot-on-block - a physical address
。
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:53140678334596
Tom's Followup 2008年12月1日 - 上午6点中央时区:
很可能D会在表中“第一” - 因为它接管了A的位置。如果rowid总是“增长”,那么空间将永远不会被重用(这将意味着rowid总是在增长 - 我们将永远无法重用旧空间,因为rowid只是一个文件.block.slot-on-阻止 - 物理地址)
答案 1 :(得分:3)
引用AskTom:
在插入时将rowid分配给一行,并且是不可变的(永不改变)...除非该行 被删除并重新插入(意思是它是另一行,而不是同一行!)
您提供的查询依赖于该rowid,并按key_values
为基础删除rowid值高于最小值的所有行。因此,删除任何重复项。
您提供的子查询是一个相关子查询,因为子查询中的表引用与子查询外部的表引用之间存在关系。
答案 2 :(得分:3)
Rowid
是一个伪列,用于唯一标识表中的每一行;它是数字。
此查询查找A
中A.key_values = B.key_values
所有行,并删除所有行,但只删除rowid
。这只是一种随意选择一个副本来保存的方法。
答案 3 :(得分:1)
ROWID
是一个为插入的每个新行递增的数字。因此,如果您有两个ROWID
数字16& 24,你知道在24之前插入了16。你的delete
语句正在删除所有重复项,只保留插入的第一个重复项。有意义??