oracle sqlcode 多条,SQL查询以连接Oracle中多个行的列值
是否有可能構(gòu)造SQL來(lái)連接列值
多行?
以下是一個(gè)示例:
表A
PID
A
B
C
表B
PID ? SEQ ? ?DESC
A ? ? 1 ? ? ?Have
A ? ? 2 ? ? ?a nice
A ? ? 3 ? ? ?DAY.
B ? ? 1 ? ? ?Nice WORK.
C ? ? 1 ? ? ?Yes
C ? ? 2 ? ? ?we can
C ? ? 3 ? ? ?do
C ? ? 4 ? ? ?this WORK!
SQL的輸出應(yīng)為-
PID ? DESC
A ? ? Have a nice DAY.
B ? ? Nice WORK.
C ? ? Yes we can do this WORK!
因此,基本上,輸出表的Desc列是表B中SEQ值的串聯(lián)?
對(duì)SQL有幫助嗎?
參見(jiàn)例如:halisway.blogspot.com/2006/08/
請(qǐng)看一下這個(gè)解決方案。 這將對(duì)您有用。
有幾種方法取決于您使用的版本-請(qǐng)參見(jiàn)有關(guān)字符串聚合技術(shù)的oracle文檔。一種很常見(jiàn)的方法是使用LISTAGG:
SELECT pid, LISTAGG(DESC, ' ') WITHIN GROUP (ORDER BY seq) AS description
FROM B GROUP BY pid;
然后加入A以選擇所需的pids。
注意:LISTAGG開(kāi)箱即用,僅適用于VARCHAR2列。
在Oracle 10g中使用wm_concat()將文本以逗號(hào)分隔的序列號(hào)的升序連接起來(lái),是否可以使降序用其他東西分隔?
還有一個(gè)XMLAGG函數(shù),可用于11.2之前的版本。由于WM_CONCAT沒(méi)有Oracle的文檔記錄和支持,因此建議不要在生產(chǎn)系統(tǒng)中使用它。
使用XMLAGG,您可以執(zhí)行以下操作:
SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()')"Result"
FROM employee_names
這是什么
將employee_names表中ename列的值(用逗號(hào)連接)放在xml元素中(帶有標(biāo)簽E)
提取此文本
聚合x(chóng)ml(將其連接)
將結(jié)果列稱(chēng)為"結(jié)果"
XMLAGG適用于Oracle 12.2。而且,XLMAGG可以連接非常長(zhǎng)的字符串,而LISTAGG可能由于它們的最終長(zhǎng)度而無(wú)法連接。
使用SQL模型子句:
SQL> SELECT pid
2 ? ? ? , ltrim(sentence) sentence
3 ? ?FROM ( SELECT pid
4 ? ? ? ? ? ? ? ?, seq
5 ? ? ? ? ? ? ? ?, sentence
6 ? ? ? ? ? ? FROM b
7 ? ? ? ? ? ?model
8 ? ? ? ? ? ? ? ? ?partition BY (pid)
9 ? ? ? ? ? ? ? ? ?dimension BY (seq)
10 ? ? ? ? ? ? ? ? ?measures (descr,CAST(NULL AS varchar2(100)) AS sentence)
11 ? ? ? ? ? ? ? ? ?( sentence[any] ORDER BY seq DESC
12 ? ? ? ? ? ? ? ? ? ?= descr[cv()] || ' ' || sentence[cv()+1]
13 ? ? ? ? ? ? ? ? ?)
14 ? ? ? ? )
15 ? WHERE seq = 1
16 ?/
P SENTENCE
- ---------------------------------------------------------------------------
A Have a nice DAY
B Nice WORK.
C Yes we can do this WORK!
3 ROWS selected.
我在這里寫(xiě)過(guò)。而且,如果您單擊指向OTN線程的鏈接,則會(huì)發(fā)現(xiàn)更多內(nèi)容,包括性能比較。
LISTAGG分析功能是在Oracle 11g第2版中引入的,這使得聚集字符串非常容易。
如果您使用的是11g第2版,則應(yīng)使用此函數(shù)進(jìn)行字符串聚合。
請(qǐng)參考以下網(wǎng)址,以獲取有關(guān)字符串連接的更多信息。
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
字符串串聯(lián)
正如大多數(shù)答案所暗示的,LISTAGG是顯而易見(jiàn)的選擇。但是,LISTAGG的一個(gè)令人討厭的方面是,如果串聯(lián)字符串的總長(zhǎng)度超過(guò)4000個(gè)字符(SQL中VARCHAR2的限制),則會(huì)引發(fā)以下錯(cuò)誤,這在Oracle 12.1版之前的版本中很難管理。
ORA-01489: result of string concatenation is too long
12cR2中添加的新功能是LISTAGG的ON OVERFLOW子句。
包含此子句的查詢?nèi)缦滤?#xff1a;
SELECT pid, LISTAGG(DESC, ' ' ON overflow TRUNCATE) WITHIN GROUP (ORDER BY seq) AS DESC
FROM B GROUP BY pid;
以上將輸出限制為4000個(gè)字符,但不會(huì)引發(fā)ORA-01489錯(cuò)誤。
這些是ON OVERFLOW子句的一些其他選項(xiàng):
ON OVERFLOW TRUNCATE 'Contd..':這將在以下位置顯示'Contd..'
字符串的結(jié)尾(默認(rèn)為...)
ON OVERFLOW TRUNCATE '':這將顯示4000個(gè)字符
沒(méi)有任何終止字符串。
ON OVERFLOW TRUNCATE WITH COUNT:這將顯示總數(shù)
終止字符后的末尾字符數(shù)。
例如:-'...(5512)'
ON OVERFLOW ERROR:如果您期望LISTAGG失敗并顯示
ORA-01489錯(cuò)誤(仍然是默認(rèn)值)。
對(duì)于必須使用Oracle 9i(或更早版本)解決此問(wèn)題的用戶,您可能需要使用SYS_CONNECT_BY_PATH,因?yàn)長(zhǎng)ISTAGG不可用。
為了回答OP,以下查詢將顯示表A中的PID并連接表B中的所有DESC列:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT a.pid, seq, description
FROM table_a a, table_b b
WHERE a.pid = b.pid(+)
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
在某些情況下,鍵和值都包含在一個(gè)表中。在沒(méi)有表A且僅存在表B的情況下,可以使用以下查詢:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT pid, seq, description
FROM table_b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
所有值都可以根據(jù)需要重新排序。各個(gè)串聯(lián)的描述可以在PARTITION BY子句中重新排序,而PID列表可以在最終的ORDER BY子句中重新排序。
或者:有時(shí)您可能希望將整個(gè)表中的所有值連接成一行。
這里的關(guān)鍵思想是為要連接的一組描述使用人工值。
在以下查詢中,使用常量字符串" 1",但是任何值都可以使用:
SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
FROM (
SELECT '1' unique_id, b.pid, b.seq, b.description
FROM table_b b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1;
各個(gè)串聯(lián)的描述可以在PARTITION BY子句中重新排序。
此頁(yè)面上的其他幾個(gè)答案也提到了這個(gè)非常有用的參考:
https://oracle-base.com/articles/misc/string-aggregation-techniques
如果必須進(jìn)行排序,LISTAGG可提供最佳性能(00:00:05.85)
SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description
FROM B GROUP BY pid;
如果不需要排序,COLLECT可以提供最佳性能(00:00:02.90):
SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
按順序進(jìn)行收藏會(huì)比較慢(00:00:07.08):
SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
所有其他技術(shù)都比較慢。
詳細(xì)說(shuō)明您的答案會(huì)有所幫助。
John,我不想在文章中重復(fù),但總而言之,這些是以下結(jié)果:1.如果必須進(jìn)行排序,則LISTAGG可以提供最佳性能(00:00:05.85)2.如果不需要進(jìn)行排序,則COLLECT可以提供最佳性能( 00:00:02.90):SELECT pid,TO_STRING(CAST(COLLECT(Desc)AS varchar2_ntt))AS Vals FROM B GROUP BY pid; 3.按順序進(jìn)行收集會(huì)比較慢(00:00:07.08):SELECT pid,TO_STRING(CAST(COLLECT(Desc ORDER BY Desc)AS varchar2_ntt))AS Vals FROM B GROUP BY pid;所有其他技術(shù)都比較慢。
您可以只編輯答案以包括相關(guān)信息。
我在編輯中為時(shí)已晚,這就是為什么我再次添加它。抱歉,我是新來(lái)的,剛開(kāi)始了解它。
在運(yùn)行選擇查詢之前,請(qǐng)運(yùn)行以下命令:
SET SERVEROUT ON SIZE 6000
SELECT XMLAGG(XMLELEMENT(E,SUPLR_SUPLR_ID||',')).EXTRACT('//text()')"SUPPLIER"
FROM SUPPLIERS;
我使用LISTAGG,但是將此字符串返回波斯字符串!
我的查詢:
SELECT
listagg(DESCRIPTION,' , ') WITHIN GROUP (ORDER BY DESCRIPTION)
FROM
B_CEREMONY
結(jié)果:
'A7'1 , ,4F
請(qǐng)幫我。
哇,這個(gè)解決方案是可行的:
SELECT listagg(CONVERT(DESCRIPTION, 'UTF8', 'AL16UTF16'),' , ') WITHIN GROUP
(ORDER BY DESCRIPTION)
FROM ?B_CEREMONY;
試試這個(gè)代碼:
SELECT XMLAGG(XMLELEMENT(E,fieldname||',')).EXTRACT('//text()')"FieldNames"
FROM FIELD_MASTER
WHERE FIELD_ID > 10 AND FIELD_AREA != 'NEBRASKA';
在選擇要串聯(lián)的位置,調(diào)用SQL函數(shù)。
例如:
SELECT PID, dbo.MyConcat(PID)
FROM TableA;
然后對(duì)于SQL函數(shù):
FUNCTION MyConcat(@PID VARCHAR(10))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @x VARCHAR(1000);
SELECT @x = isnull(@x +',', @x, @x +',') + DESC
FROM TableB
WHERE PID = @PID;
RETURN @x;
END
函數(shù)頭語(yǔ)法可能是錯(cuò)誤的,但是該原理確實(shí)有效。
這對(duì)Oracle無(wú)效
總結(jié)
以上是生活随笔為你收集整理的oracle sqlcode 多条,SQL查询以连接Oracle中多个行的列值的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 胰腺癌吃点什么中药能延长生命期(胰腺癌吃
- 下一篇: 衣服上的墨汁怎么洗掉小窍门(墨汁可以洗掉