1. 程式人生 > >ORACLE單行轉多行、ORACLE遞迴查詢

ORACLE單行轉多行、ORACLE遞迴查詢

ORACLE單行轉多行

WITH TESTTABLE AS (
	SELECT 'TEST1' GROUPNAME , 'A,B,C,D,E' VALUENAME FROM DUAL
	UNION ALL
	SELECT 'TEST2' GROUPNAME , 'A,B,C,D' VALUENAME FROM DUAL
)
SELECT
			GROUPNAME,
			SUBSTR( A.VALUENAME, INSTR( A.VALUENAME, ',', 1, LEVELS.LVL ) + 1, INSTR( A.VALUENAME, ',', 1, LEVELS.LVL + 1 ) -( INSTR( A.VALUENAME, ',', 1, LEVELS.LVL ) + 1 )) AS VALUENAME
		FROM
			(
				SELECT
					GROUPNAME,
					',' || VALUENAME || ',' AS VALUENAME,
					LENGTH(VALUENAME) - NVL( LENGTH( REPLACE( VALUENAME, ',' )), 0 ) + 1 AS CNT
					--取待拆分欄位每行按照分隔符','分割後的記錄數,用於CONNECT BY
				FROM
					TESTTABLE
			) A,
			(
				SELECT
					ROWNUM AS LVL
					--產生一個待拆分欄位分割後最大記錄數的序列
				FROM
					(
						SELECT
							MAX( LENGTH( VALUENAME || ',' ) - NVL( LENGTH( REPLACE( VALUENAME, ',' )), 0 )) MAX_LEN
						FROM
							TESTTABLE
					)
				CONNECT BY
					LEVEL <= MAX_LEN
			) LEVELS
		WHERE
			LEVELS.LVL <= A.CNT
			--笛卡爾連線
		ORDER BY
			GROUPNAME

ORACLE遞迴查詢

WITH TESTTABLE AS (
	SELECT '0' ID, 'TEST1' NAME,'' PID, 1 SORTBY FROM DUAL
	UNION ALL
	SELECT '1' ID, 'TEST1-1' NAME,'0' PID, 1 SORTBY FROM DUAL
	UNION ALL
	SELECT '2' ID, 'TEST1-2' NAME,'0' PID, 1 SORTBY FROM DUAL
	UNION ALL
	SELECT '3' ID, 'TEST1-3' NAME,'0' PID, 1 SORTBY FROM DUAL
	UNION ALL
	SELECT '11' ID, 'TEST1-1-1' NAME,'1' PID, 1 SORTBY FROM DUAL
	UNION ALL
	SELECT '12' ID, 'TEST1-1-2' NAME,'1' PID, 2 SORTBY FROM DUAL
	UNION ALL
	SELECT '13' ID, 'TEST1-1-3' NAME,'1' PID, 3 SORTBY FROM DUAL
)
SELECT ID,
                     (CASE
                         WHEN LEVEL < 2 THEN '<>'
                         ELSE LPAD (' ', LEVEL * 2, ' ') || '|- '
                      END)
                  || NAME
                     NAME,
                  NAME DEPTITLE,
                  SUBSTR(SYS_CONNECT_BY_PATH(NAME, '>'), 2) NAME_PATH,
                  CONNECT_BY_ROOT(NAME) TOPDEP,
                  CONNECT_BY_ISLEAF ISLEAF,
                  LEVEL,
                  PID
             FROM TESTTABLE
       START WITH PID IS NULL
       CONNECT BY PRIOR ID = PID
ORDER SIBLINGS BY SORTBY

說明:

  1. CONNECT_BY_ROOT 返回當前節點的最頂端節點
  2. CONNECT_BY_ISLEAF 判斷是否為葉子節點,如果這個節點下面有子節點,則不為葉子節點
  3. LEVEL 偽列表示節點深度
  4. SYS_CONNECT_BY_PATH函式顯示詳細路徑,並用“>”分隔