我是我职业生涯的新手……
我正在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之后预期“加入”
你可以帮我吗…我需要它作为查询,因为我没有权限通过客户端策略在数据库上创建函数和过程,我需要尽可能快
解决方法
SQL Server和Oracle 11g是非常不同的RDBMS并且支持不同的语法(不包括ANSI标准部分),因此您不能使用CROSS APPLY和XML.
但您可以使用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)
SqlFiddleDemo
输出:
╔═════════╦═══════════╗ ║ FAMILY ║ PERSONSID ║ ╠═════════╬═══════════╣ ║ 1 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 5 ║ ║ 2 ║ 6 ║ ║ 2 ║ 7 ║ ║ 2 ║ 10 ║ ╚═════════╩═══════════╝
对于长度超过一个字符的分隔符,您可以使用稍微修改过的查询here.
编辑:
DISTINCT将删除重复项,以便何时删除
PersonsID 1#1#2#5 => 1 2 5
要获取具有重复项的所有值,请删除DISTINCT:
=> 1 1 2 5