CREATE TABLE b(ID VARCHAR2(50 BYTE),
PARENT_ID VARCHAR2(50 BYTE),
NAME NVARCHAR2(200)
);
https://community.oracle.com/thread/3513540?分层表多次合并
上面的链接我解释了一切
CREATE TABLE b(ID VARCHAR2(50 BYTE),
PARENT_ID VARCHAR2(50 BYTE),
NAME NVARCHAR2(200)
);
https://community.oracle.com/thread/3513540?分层表多次合并
上面的链接我解释了一切
任何原因,你不喜欢answer posted there? SQL Fiddle是否说明了问题的答案,而不是您描述的所需结果?
编辑:
一种SQL Fiddle使用该技术Frank Kulashsuggested。这是自2002年以来第一个基于Oracle的查询(在9iAS上)。
SELECT REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, 1) Header1,
REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, 1) Header2,
REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, 1) Header3,
REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, 2) Header4,
REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, 2) Header5,
REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, 2) Header6,
REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, 3) Header7,
REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, 3) Header8,
REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, 3) Header9,
REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, 4) Header10,
REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, 4) Header11,
REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, 4) Header12,
REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, 5) Header13,
REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, 5) Header14,
REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, 5) Header15
--,REGEXP_SUBSTR(a.PIDPath, '[^,]+', 1, n)
--,REGEXP_SUBSTR(a.IDPath, '[^,]+', 1, n)
--,REGEXP_SUBSTR(a.NamePath, '[^,]+', 1, n)
FROM ( SELECT LEVEL RootLvl,
b.ID RootID,
SYS_CONNECT_BY_PATH(b.PARENT_ID, ',')
|| ',' PIDPath,
SYS_CONNECT_BY_PATH(b.ID, ',')
|| ',' IDPath,
SYS_CONNECT_BY_PATH(b.NAME, ',')
|| ',' NamePath
FROM t b
START WITH b.PARENT_ID = '1'
CONNECT BY NOCYCLE PRIOR b.ID = b.PARENT_ID) a
ORDER BY a.RootLvl, a.RootID;
弗兰克Kulash指出:
结果集中的列数必须是硬编码到查询。你今天可以编写一些能够产生30列的东西(也就是说,对于层次结构中的10个层次来说足够了),但是如果你稍后改变了数据以便有11个或更多的层次,那么你的查询就会开始失去结果。
我可能会回来尝试一下PIVOT
事情。甲骨文很疯狂。
编辑:
但足够管理。静态的PIVOT
工程just fine。我不能得到CROSS APPLY
像我认为它应该与VALUES
(MSSQL风格)一样工作,所以我已经放弃并代之以通过UNION ALL
。这个动态SQL可能会有一些工作,所以它实际上可以在不对列进行硬编码的情况下完成你所需要的工作。
;
WITH c (RID, ID, PARENT_ID, NAME) AS (
SELECT ROW_NUMBER() OVER (
ORDER BY PARENT_ID) RID,
ID, PARENT_ID, NAME
FROM t
UNION ALL
SELECT b.RID, a.ID, a.PARENT_ID, a.NAME
FROM t a,
c b
WHERE a.ID = b.PARENT_ID
)
SELECT p."'ID_1'" Header1,
p."'PARENT_ID_1'" Header2,
p."'NAME_1'" Header3,
p."'ID_2'" Header4,
p."'PARENT_ID_2'" Header5,
p."'NAME_2'" Header6,
p."'ID_3'" Header7,
p."'PARENT_ID_3'" Header8,
p."'NAME_3'" Header9,
p."'ID_4'" Header10,
p."'PARENT_ID_4'" Header11,
p."'NAME_4'" Header12,
p."'ID_5'" Header13,
p."'PARENT_ID_5'" Header14,
p."'NAME_5'" Header15
FROM ( SELECT RID,
'ID_' || ROW_NUMBER() OVER (
PARTITION BY RID
ORDER BY ID) KeyName,
ID KeyValue
FROM c
UNION ALL
SELECT RID,
'PARENT_ID_' || ROW_NUMBER() OVER (
PARTITION BY RID
ORDER BY ID) KeyName,
PARENT_ID KeyValue
FROM c
UNION ALL
SELECT RID,
'NAME_' || ROW_NUMBER() OVER (
PARTITION BY RID
ORDER BY ID) KeyName,
CAST(NAME AS VARCHAR2(200)) KeyValue
FROM c) s
PIVOT (MAX(KeyValue) FOR KeyName IN (
'ID_1', 'PARENT_ID_1', 'NAME_1',
'ID_2', 'PARENT_ID_2', 'NAME_2',
'ID_3', 'PARENT_ID_3', 'NAME_3',
'ID_4', 'PARENT_ID_4', 'NAME_4',
'ID_5', 'PARENT_ID_5', 'NAME_5')) p
ORDER BY p.RID;
是的,当然如果你仔细看看我说明的表格然后你会发现它们不是一样的输出 – user3283992
没有看到,但还有更多的建议。我猜你想要的更接近我发布的第二件事情 - 可以动态生成以获得更多灵活性。 – Avarkx
请不要用链接描述问题。该链接可能在将来不存在。编辑您的问题并添加相关信息。 –
对不起,我会尽快编辑它 – user3283992
现代的方式是递归CTE http://stackoverflow.com/questions/4659803/recursion-in-oracle – jbaliuka