如何编写oracle Query将字符串拆分为多个按类别相关的行

时间:2015-12-27 17:19:59

标签: oracle

我刚从事我的职业生涯.. 我正在Visual Studio数据工具上构建一个SSAS模型。 我遇到的最复杂问题之一是一个字段包含多个值,我需要将它们连接到另一个表,例如。

Family   PersonsID 
1         1#2#5 
2         6#7#10

我想要一个查询“而不是一个plsql程序”来使它成为这种形式

Family  PersonsID
1          1
1          2
1          5
2          6
2          7
2          10

用Persons Table绑定它。 我找到了这个天才查询

SELECT A.[Family],  
     Split.a.value('.', 'VARCHAR(100)') AS String  
 FROM  (SELECT [State],  
         CAST ('<M>' + REPLACE([PersonsID], '#', '</M><M>') + '</M>' AS XML) AS String  
     FROM  TableA) AS A CROSS APPLY String.nodes ('/M') AS Split(a);

它完全按照我的意愿完成,但仅限于SQL服务器。当我在Oracle 11g上尝试它时 它给了我错误:在Cross之后预期“加入”

你可以帮助我..我需要它作为查询,因为我没有权限通过客户端策略在数据库上创建函数和过程,我需要尽快

2 个答案:

答案 0 :(得分:4)

Oracle 11gCROSS APPLY and XML是非常不同的RDBMS,支持不同的语法(不包括ANSI标准部分),因此您无法使用regexp_substr

但您可以改为使用SELECT DISTINCT t.Family, TRIM(regexp_substr(t.PersonsID, '[^#]+', 1, levels.column_value)) AS PersonsID FROM TableA t, table(cast(multiset(select level from dual connect by level <= length ( regexp_replace(t.PersonsID, '[^#]+')) + 1) as sys.OdciNumberList)) levels ORDER BY Family, CAST(PersonsID AS INT)

╔═════════╦═══════════╗
║ FAMILY  ║ PERSONSID ║
╠═════════╬═══════════╣
║      1  ║         1 ║
║      1  ║         2 ║
║      1  ║         5 ║
║      2  ║         6 ║
║      2  ║         7 ║
║      2  ║        10 ║
╚═════════╩═══════════╝   

SqlFiddleDemo

输出:

DISTINCT

对于长度超过一个字符的分隔符,您可以使用稍微修改后的查询here

修改

PersonsID 1#1#2#5 => 1 2 5 将删除重复项,以便

DISTINCT

要获取包含重复项的所有值,请移除=> 1 1 2 5

+--------------+-----------+-------------------------+
|Column name   |Data type  |Description              |
+--------------+-----------+-------------------------+
|is_filetable  |bit        |1 = Table is a FileTable |
+--------------+-----------+-------------------------+

答案 1 :(得分:1)

以下是实现相同结果的另一种方法

SELECT family , trim(COLUMN_VALUE) PersonsID
FROM table1, xmltable(('"' || REPLACE(PersonsID, '#', '","') || '"'))