ORACLE SQL DEVELOPER的更新查询

ORACLE SQL DEVELOPER的更新查询,sql,oracle,sql-update,Sql,Oracle,Sql Update,我有四个专栏 身份证件 第一个名字 姓 城市 101 A. B C 303 A. B C 207 A. B C 55 X Y Z 67 X Y Z 200 X Y Z 这里有一种方法-将您的表连接到聚合查询的结果,并按fn、ln、city更新组,筛选出具有单个id的组,然后在其余组中选择minid,然后使用该值进行更新 设置测试用例: create table my_table (id, first_name, last_name, city) as select 101, 'A', 'B'

我有四个专栏

身份证件 第一个名字 姓 城市 101 A. B C 303 A. B C 207 A. B C 55 X Y Z 67 X Y Z 200 X Y Z
这里有一种方法-将您的表连接到聚合查询的结果,并按fn、ln、city更新组,筛选出具有单个id的组,然后在其余组中选择minid,然后使用该值进行更新

设置测试用例:

create table my_table (id, first_name, last_name, city) as
  select 101, 'A', 'B', 'C' from dual union all
  select 303, 'A', 'B', 'C' from dual union all
  select 207, 'A', 'B', 'C' from dual union all
  select  55, 'X', 'Y', 'Z' from dual union all
  select  67, 'X', 'Y', 'Z' from dual union all
  select 200, 'X', 'Y', 'Z' from dual union all
  select 333, 'D', 'F', 'G' from dual
;

Table MY_TABLE created.
更新:

update
( select t.id, g.min_id
  from   my_table t
         inner join
         ( select min(id) as min_id, first_name, last_name, city
           from   my_table
           group  by first_name, last_name, city
           having min(id) != max(id)
         ) g
         using (first_name, last_name, city)
)
set id = min_id
where id != min_id
;

4 rows updated.
检查结果:

select * from my_table;

        ID FIRST_NAME LAST_NAME  CITY      
---------- ---------- ---------- ----------
       101 A          B          C         
       101 A          B          C         
       101 A          B          C         
        55 X          Y          Z         
        55 X          Y          Z         
        55 X          Y          Z         
       333 D          F          G   
注意:如果ID可能为null,则需要进行一些额外的处理,但列不应为null。。。。是吗?

一个选项是使用最小分析函数进行分组,通过以下合并语句重复三列:first\u name、last\u name、city

MERGE INTO tab t1
USING ( SELECT MIN(id) OVER (PARTITION BY first_name, last_name, city) AS new_id
          FROM tab t ) t2
   ON ( t1.rowid = t2.rowid )                 
 WHEN MATCHED THEN UPDATE SET t1.id = t2.new_id

我会选择一个相关子查询:

update t1 
set id = (
    select min(id) 
    from mytable t1 
    where t1.first_name = t.first_name and t1.lastname = t.lastname and t1.city = t.city
)
where id > (
    select min(id) 
    from mytable t1 
    where t1.first_name = t.first_name and t1.lastname = t.lastname and t1.city = t.city
)

此查询将利用firstname、lastname、city、id上的索引-尽管更新行也需要更新索引…

您的查询比需要的复杂得多。你有两个或更多?!选择查询的级别。您应该重构它以使用CTE和联接,而不是让x在SELECT中的所有连接。另外,请使用比表更好的占位符名称,因为这是SQL中的一个关键字,使您的查询更难阅读。当然,请欣赏关于表的建议,它只是引用任何表。但是有什么方法可以使用rownum实现这一点吗?左对齐SQL非常难读,而且写…@jarlh我认为是因为没有任何缩进,加上在第7行的大写字母锁关闭之前有一半是大写的,这使得它很难读。此外,表中的first_name、last_name、city中的构造也没有任何意义-可能缺少select关键字。Id不为null,尽管某些Id的其他列为null。您可以解释一下rowid匹配如何在分区you's welcome@Rishu Tripathi上工作吗。实际上,我们通常不会在SQL语句中使用rowid值。因为,它们只是物理地址,并且随着某些磁盘操作(如移动、收缩)的应用而变化。。在这种情况下,即使发生了更改,也没有问题,因为对于主查询和子查询,我们仍然保持在同一个表中,并且ise具有唯一的值。