2015-09-02 103 views
4

這是一個樣表數據串接在甲骨文

Fruit Number 
Apple 1 
Apple 2 
Apple 3 
Kiwi  6 
Kiwi  10 

我會再做連接表列值得到以下

Fruit Number 
Apple 1-2-3 
Kiwi  6-10 

有沒有一種方法來查詢這個或存儲過程? 像連接(分區)之類的東西,我不太瞭解存儲過程。謝謝!

+1

什麼是您的Oracle數據庫版本? 'LISTAGG'從11g開始可用。否則,請在Google搜索** **中的字符串聚合技術。 –

+1

看到這個答案http://stackoverflow.com/a/28690752/3989608 –

+1

感謝版本是10克,所以我不能真正使用Listagg。還有其他方法可以做到嗎? – Sailormoon

回答

1

OP是在Oracle 10克,和LISTAGG11g第2版引入。

因此,在甲骨文之前版本到11g其中LISTAGG不支持,你可以使用ROW_NUMBER()SYS_CONNECT_BY_PATH功能。

SELECT fruit, 
    LTRIM(MAX(SYS_CONNECT_BY_PATH(number,',')) 
    KEEP (DENSE_RANK LAST ORDER BY curr),',') AS fruits_agg 
    FROM (SELECT fruit, 
       number, 
       ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) AS curr, 
       ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) -1 AS prev 
     FROM table_name) 
    GROUP BY fruit 
    CONNECT BY prev = PRIOR curr AND fruit = PRIOR fruit 
START WITH curr = 1; 

注意

切勿使用WM_CONCAT因爲它是一個未公開的特性,它已經從12C版本中刪除。

已經依賴wm_concat函數的任何應用程序在升級到12c後將不起作用。因爲它已被刪除。見Why not use WM_CONCAT function in Oracle?

SQL> select banner from v$version where rownum = 1; 

BANNER 
---------------------------------------------------------------------------- 
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 

SQL> SELECT object_name 
    2 FROM dba_objects 
    3 WHERE owner='WMSYS' 
    4 AND object_name LIKE 'WM\_%' ESCAPE '\'; 

OBJECT_NAME 
---------------------------------------------------------------------------- 
WM_REPLICATION_INFO 
WM_RDIFF 
WM_PERIOD 
WM_PERIOD 
WM_OVERLAPS 
WM_MEETS 
WM_LESSTHAN 
WM_LDIFF 
WM_INTERSECTION 
WM_INSTALLATION 
WM_GREATERTHAN 
WM_EVENTS_INFO 
WM_ERROR 
WM_ERROR 
WM_EQUALS 
WM_DDL_UTIL 
WM_DDL_UTIL 
WM_CONTAINS 
WM_COMPRESS_BATCH_SIZES 
WM_COMPRESSIBLE_TABLES 

20 rows selected. 

SQL> 

,您會收到一個「無效的標識符」錯誤:

SQL> SELECT banner FROM v$version; 

BANNER 
---------------------------------------------------------------------------- 
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 
PL/SQL Release 12.1.0.1.0 - Production 
CORE 12.1.0.1.0  Production 
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production 
NLSRTL Version 12.1.0.1.0 - Production 

SQL> SELECT deptno, wm_concat(ename) FROM emp; 
SELECT deptno, wm_concat(ename) FROM emp 
       * 
ERROR at line 1: 
ORA-00904: "WM_CONCAT": invalid identifier 

因此,沒有一點依靠的無證功能這是沒有更多的最新版本提供。

+0

_Never使用WM_CONCAT_ - 爲什麼不?如果你有一個例子,你總是可以將它重新添加到12c中。 [這裏](http://stackoverflow.com/a/22145391/1990451)(這也是我的答案btw指出)。 – smnbbrv

+0

@smnbbrv也許你不關心你的數據庫和Oracle支持的需求。如果說某個功能*沒有記錄*,則表示如果出現問題,那麼您將自行處理。你如何在生產環境中處理這些事情?或者你不在乎? –

+0

當你遇到問題時,你首先來到StackOverflow,並且你並不孤單。我的現場系統已經啓動,並且一直在運行並且很有趣,但是Oracle支持從未幫助過我,可能是因爲它們只是像你一樣炫耀。你相信你是對的,但事實是,我的回答被5人和你的回答所接受,可能這不是事實。您的行爲讓我再次想到再次去Oracle支持之前 – smnbbrv

8

您不需要爲此存儲過程。使用listagg功能:

select fruit, listagg(number, ',') within group (order by number) 
from mytable 
group by fruit 

如果你的數據庫版本爲10g它仍然是簡單:使用WM_CONCAT(如果不能識別名稱可能會嘗試WMSYS.WM_CONCAT)功能,請參閱this回答樣本。如果您需要使用與,不同的分隔符,您可以將結果打包在replace函數中;如果您想訂購的結果只是預購它在一個子查詢,如:

select fruit, replace(wm_concat(number), ',', '-') 
from (select fruit, number 
     from mytable 
     order by number) 
group by fruit 

如果你對某些神祕的原因沒有在您的實例功能,您可以使用一個填充工具,看我的回答here

+0

不幸的是,OP在'10g'上,而'LISTAGG'不被支持,因爲它是在'11gR2'中引入的。 10g中另一個解決方案是'ROW_NUMBER()'和'SYS_CONNECT_BY_PATH'函數。 –

+0

@LalitKumarB這也可以用'wm_concat'函數進行,而不用做不必要的遞歸查詢。見例如這個答案http://stackoverflow.com/a/4970624/1990451 – smnbbrv

+0

不要使用**'WM_CONCAT' **,因爲它是一個**未記錄的功能**,它在Oracle 12c **中完全刪除**。不要只依賴別人的答案,但請花點時間學習和理解事實。請參閱[爲什麼不在Oracle中使用WM_CONCAT函數?](http://lalitkumarb.com/2015/04/29/why-not-use-wm_concat-function-in-oracle/) –