【问题标题】:SQL query update by grouping通过分组更新 SQL 查询
【发布时间】:2012-11-01 23:28:30
【问题描述】:

我正在处理 Oracle 表中的一些遗留数据,并且有以下内容

--------------------------------------------
| RefNo                         |     ID   |                          
--------------------------------------------
| FOO/BAR/BAZ/AAAAAAAAAA        |      1   |
| FOO/BAR/BAZ/BBBBBBBBBB        |      1   |
| FOO/BAR/BAZ/CCCCCCCCCC        |      1   |
| FOO/BAR/BAZ/DDDDDDDDDD        |      1   |
--------------------------------------------

对于每个 /FOO/BAR/BAZ/% 记录,我想让 ID 成为唯一的递增数字。 有没有办法在 SQL 中做到这一点?

提前致谢

编辑

抱歉,没有具体说明。我有几组记录/FOO/BAR/BAZ/、/FOO/ZZZ/YYY/。这些其他(示例)组中的每一个都需要进行相同的转换。不能使用 recnum 我希望 ID 从 1 开始,递增,对于我必须更改的每组记录。

很抱歉弄乱了我的第一篇文章。输出应该是

--------------------------------------------
| RefNo                         |     ID   |                          
--------------------------------------------
| FOO/BAR/BAZ/AAAAAAAAAA        |      1   |
| FOO/BAR/BAZ/BBBBBBBBBB        |      2   |
| FOO/BAR/BAZ/CCCCCCCCCC        |      3   |
| FOO/BAR/BAZ/DDDDDDDDDD        |      4   |
| FOO/ZZZ/YYY/AAAAAAAAAA        |      1   |
| FOO/ZZZ/YYY/BBBBBBBBBB        |      2   |
--------------------------------------------

【问题讨论】:

  • Avalanche:RefNo 可以重复吗?如果是,那么您是否希望重复的 Refno 具有相同的 ID 或不同的唯一 ID?

标签: sql oracle


【解决方案1】:

让我们尝试这样的事情(Oracle 10g 及更高版本):

SQL> with t1 as(
  2    select 'FOO/BAR/BAZ/AAAAAAAAAA' as RefNo,  1 as ID from dual union all
  3    select 'FOO/BAR/BAZ/BBBBBBBBBB',  1 from dual union all
  4    select 'FOO/BAR/BAZ/CCCCCCCCCC',  1 from dual union all
  5    select 'FOO/BAR/BAZ/DDDDDDDDDD',  1 from dual union all
  6    select 'FOO/ZZZ/YYY/AAAAAAAAAA',  1 from dual union all
  7    select 'FOO/ZZZ/YYY/BBBBBBBBBB',  1 from dual union all
  8    select 'FOO/ZZZ/YYY/CCCCCCCCCC',  1 from dual union all
  9    select 'FOO/ZZZ/YYY/DDDDDDDDDD',  1 from dual
 10  )
 11  select row_number() over(partition by ComPart order by DifPart) as id
 12       , RefNo
 13     From (select regexp_substr(RefNo, '[[:alpha:]]+$')   as DifPart
 14                , regexp_substr(RefNo, '([[:alpha:]]+/)+') as ComPart
 15                , RefNo
 16                , Id
 17             from t1
 18           ) q
 19  ;

        ID REFNO
---------- -----------------------
         1 FOO/BAR/BAZ/AAAAAAAAAA
         2 FOO/BAR/BAZ/BBBBBBBBBB
         3 FOO/BAR/BAZ/CCCCCCCCCC
         4 FOO/BAR/BAZ/DDDDDDDDDD
         1 FOO/ZZZ/YYY/AAAAAAAAAA
         2 FOO/ZZZ/YYY/BBBBBBBBBB
         3 FOO/ZZZ/YYY/CCCCCCCCCC
         4 FOO/ZZZ/YYY/DDDDDDDDDD

我认为实际更新ID 列并不是一个好主意。每次添加新的数据组时,都必须再次运行更新语句。更好的方法是创建一个视图,每次查询时都会看到所需的输出。

【讨论】:

  • 在 10G 上运行这个我在第 1 行得到“with t1(RefNo, ID) as(”错误:ORA-32033: 不支持的列别名。
  • @Dr.Avalanche 抱歉,这是正确的,因为 10g 不支持查询的 with 子句中的列别名。我已经更新了答案。 With 部分查询包含来自您问题的数据样本。您可以只进行一个查询(将 from 子句中的表名从 t1 更改为您的表名)并在您的数据上进行尝试。
  • 理想。有没有办法改变查询以针对实际表中的列名运行?
【解决方案2】:

rownum可以作为递增ID吗?

UPDATE legacy_table
    SET id = ROWNUM;

这将为表中的所有记录分配唯一值。 This link contains documentation about Oracle Pseudocolumn.

【讨论】:

  • 抱歉没有具体说明,我会更新上面的问题。表中还有其他记录我要更新
【解决方案3】:

您可以运行以下命令:

update <table_name> set id = rownum where descr like 'FOO/BAR/BAZ/%'

【讨论】:

    【解决方案4】:

    这很粗略,我不确定您的 RefNo 是否是单值列,或者您只是为了简单而这样做。

    select 
        sub.RefNo
        row_number() over (order by sub.RefNo) + (select max(id) from TABLE),
    
    from (
        select FOO+'/'+BAR+'/'+BAZ+'/'+OTHER as RefNo
        from TABLE
        group by FOO+'/'+BAR+'/'+BAZ+'/'+OTHER
    ) sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-11
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多