我在这里看到有关将数据值拆分为行的其他解决方案,但到目前为止,它们都不能在Sybase IQ上运行 - 因为它不受支持或者我没有正确的创建过程的访问权限。我可以在Java中轻松完成这项工作,但尝试在查询中执行此操作,以便我可以避免开销。
所以我要做的就是拿这个......
ID | Data
abc | 18,20,22
def | 17,19
ghi | 13,19
并将其转换为......
ID | Data
abc | 18
abc | 20
abc | 22
def | 17
def | 19
ghi | 13
ghi | 19
我尝试了递归方法但遇到了远程服务器不支持它的错误
我尝试了下面的XML版本但是我在最后一行上遇到了语法错误。我唯一能想到的就是不支持Cross Apply,因为Aqua Data没有突出显示这个词,因为它与其他所有内容一样。
SELECT A.ID,
Split.a.value('.', 'VARCHAR(100)') AS Data
FROM
(
SELECT ID,
CAST ('<M>' + REPLACE(Data, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM mytable
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);
由于权限
我尝试使用这个Sybase函数(sa-split-list)...
http://dcx.sybase.com/1200/en/dbreference/sa-split-list-sysproc.html
但不确定如何加入
任何人都可以提供帮助吗?
答案 0 :(得分:0)
我认为可以使用递归查询来完成,例如:
with recursive temp (n, ID, init_str, next_comma, value, str) as (
select 0, ID, data as init_str, cast(null as integer), cast(null as varchar(200)), init_str as str
from (
select 'abc' as ID, '18,20,22' as Data union
select 'def' as ID, '17,19' as Data union
select 'ghi' as ID, '5' as Data
) mydata
union all
select n+1, ID, init_str, locate(str, ',')
, case when locate (str, ',') = 0 then str else substr(trim(str), 0, locate (str, ',')) end
, case when locate(str, ',') = 0 then '' else substr(trim(str), locate(str, ',')+1) end
from temp
where len(trim(str)) > 0
)
select *
from temp
where value is not null
;
不幸的是,我认为Sybase IQ只对递归有部分支持。特别是,当我用对真实表的引用替换mydata
CTE时,整个事情就会崩溃。
答案 1 :(得分:-1)
尝试使用list
功能
CREATE TABLE #T1 (ID CHAR(3),DATA CHAR(50))
INSERT INTO #T1
SELECT ID,LiST(LTRiM(RTRiM(Data))) FROM mytable GROUP BY ID
SELECT * FROM #T1