【问题标题】:SQL: how to separate combined row into individual rowsSQL:如何将组合行分成单独的行
【发布时间】:2012-05-19 03:39:12
【问题描述】:

我有一个这样的数据库表:

id   |   check_number        |   amount
1    |   1001]1002]1003      |   200]300]100
2    |   2001]2002           |   500]1000
3    |   3002]3004]3005]3007 |   100]300]600]200

我想将记录分成如下内容:

id   |   check_number    |   amount
1    |   1001            |   200
2    |   1002            |   300
3    |   1003            |   100
.    |     .             |    .
.    |     .             |    .
.    |     .             |    .

如何在 Oracle 和 SQL Server 中仅使用 SQL 来做到这一点?

谢谢,

米洛

【问题讨论】:

  • 您想用id 列做什么?为转换后的数据集生成新值?
  • sql-serveroracle?或者你真的在两个 RDBMS 上有同样的问题吗?
  • 数据的来源是什么?您可以选择在将数据加载到数据库之前重新格式化数据吗?
  • 单列中的项目数是否有限制?

标签: sql sql-server oracle stored-procedures tokenize


【解决方案1】:

仅在 Oracle 中,使用 CONNECT BY LEVEL 方法(请参阅 here),但有几个注意事项:

select rownum, id,
       substr(']'||check_number||']'
              ,instr(']'||check_number||']',']',1,level)+1
              ,instr(']'||check_number||']',']',1,level+1) 
               - instr(']'||check_number||']',']',1,level) - 1) C1VALUE,
       substr(']'||amount||']'
              ,instr(']'||amount||']',']',1,level)+1
              ,instr(']'||amount||']',']',1,level+1) 
               - instr(']'||amount||']',']',1,level) - 1) C2VALUE
    from table
connect by id = prior id and prior dbms_random.value is not null  
      and level <= length(check_number) - length(replace(check_number,']')) + 1


ROWNUM ID  C1VALUE C2VALUE

1      1   1001    200
2      1   1002    300
3      1   1003    100
4      2   2001    500
5      2   2002    1000
6      3   3002    100
7      3   3004    300
8      3   3005    600
9      3   3007    200

本质上,我们使用 oracle 的分层函数爆破查询,然后只获取 check_number 和 amount 列中每个“列”数据中的数据的子字符串。

主要警告:要转换的数据必须在两列中具有相同数量的“数据元素”,因为我们使用第一列来“计算”要转换的项目数。

我已经在 11gR2 上对此进行了测试。 YMMV 也取决于 DMBS 版本。注意需要使用“PRIOR”运算符,它可以防止 oracle 进入无限循环连接。

【讨论】:

  • 编辑 - 连接者没有 check_number。查询现在应该运行。
  • 在 SQL Server 中,您可以使用递归 CTE 执行类似的操作。
猜你喜欢
  • 1970-01-01
  • 2021-10-21
  • 2017-02-25
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多