線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:10415
推到 Plurk!
推到 Facebook!

SQL語法如何將直的資料做橫向的字串連結

尚未結案
cindyliu
一般會員


發表:16
回覆:18
積分:6
註冊:2008-09-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-12-12 00:21:07 IP:118.166.xxx.xxx 訂閱
請問各位~
這是一份類用明細表
欄位有費用類別、費用代碼、金額、備註....

TYPE CHG_CD AMT REMARK
------- --------------- --------- ----------------
01 1004 250 abcd
02 1210 200 test
01 1005 100
01 1003 150 xyz
02 1221 100 ijk
03 1010 100 efg


這是依費用類別加總,最後產出來的樣子~
TYPE AMT REMARK
------- ---------- ---------------------
01 500 abcdxyz
02 300 testijk
03 100 efg
因為前輩寫的FUNCTION是要傳入一段SQL語法去產出檔案...
目前加總的部分我OK,,,
卡在備註REMARK的地方,SQL要怎麼寫才能達到上面的結果?
請各位高手幫幫忙...感恩^^

補充一下..
因為公司有MSSQL與ORACLE,希望也能有ORACLE的寫法喔...
(目前是ORACLE 比較急需用到) 謝謝^^

編輯記錄
cindyliu 重新編輯於 2008-12-12 00:22:01, 註解 無‧
cindyliu 重新編輯於 2008-12-12 12:56:14, 註解 無‧
st33chen
尊榮會員


發表:15
回覆:591
積分:1201
註冊:2005-09-30

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-12-12 08:35:21 IP:122.116.xxx.xxx 未訂閱
您好,
1. 由 sql 產生的話要看用什麼資料庫,
mysql 直接用 group_concat (例 : select ....., group_concat(...) from ... )
oracle 的話, 請參考
http://delphi.ktop.com.tw/board.php?cid=30&fid=1498&tid=96292

2. 由 sql 產生資料後再後製作的方法的話, 也參考上列這一篇.
------
IS IT WHAT IT IS
我是 李慕白 請倒著唸.
又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦);
都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-12-12 11:06:15 IP:60.248.xxx.xxx 訂閱
HI, 除了 st33chen 前輩的兩種方式外,這邊小弟再加一個 MSSQL 呼叫 Function 的方式

以您的 Sample 的話,請建立一個 function 在 SQL Server 裡面

[code sql]
Create function StringAdd(
@TYPE nvarchar(200) -- 這個 Size 或型態請依您自己的欄位設定
) Returns nvarchar(4000)
AS
BEGIN
Declare @sTmp nvarchar(4000) ;
Set @sTmp='';
Select @sTmp=@sTmp '、' IsNull(Remark, '') from 類用明細表 where Type=@TYPE;
Return Stuff(@sTmp, 1, 1, '');
END
[/code]

然後寫下面這段 SQL 語法時,就可以寫成
[code sql]
Select Type, Sum(AMT) as AMT, dbo.StringAdd(Type) as Remark from 類用明細表 Group by Type
[/code]

===================引 用 cindyliu 文 章===================
請問各位~
這是一份類用明細表
欄位有費用類別、費用代碼、金額、備註....

TYPE CHG_CD AMT REMARK
------- --------------- --------- ----------------
01 1004 250 abcd
02 1210 200 test
01 1005 100
01 1003 150 xyz
02 1221 100 ijk
03 1010 100 efg


這是依費用類別加總,最後產出來的樣子~
TYPE AMT REMARK
------- ---------- ---------------------
01 500 abcdxyz
02 300 testijk
03 100 efg
因為前輩寫的FUNCTION是要傳入一段SQL語法去產出檔案...
目前加總的部分我OK,,,
卡在備註REMARK的地方,SQL要怎麼寫才能達到上面的結果?
請各位高手幫幫忙...感恩^^
------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-12-12 11:06:48, 註解 無‧
careychen 重新編輯於 2008-12-12 11:08:10, 註解 無‧
careychen 重新編輯於 2008-12-12 11:20:30, 註解 @@ 搞不定‧
st33chen
尊榮會員


發表:15
回覆:591
積分:1201
註冊:2005-09-30

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-12-12 12:08:04 IP:122.116.xxx.xxx 未訂閱
再參一腳, 留下記錄當作筆記
mssql 模擬 group_concat 的另一方法

select Type, substr(RestaurantNames,1,len(RestaurantNames)-1) RestaurantNames
from Restaurant AS A
CROSS APPLY (
SELECT RestaurantName ','
FROM Restaurant AS B
WHERE A.Type = B.Type
FOR XML PATH('')
) D (RestaurantNames)
GROUP BY Type, RestaurantNames
------
IS IT WHAT IT IS
我是 李慕白 請倒著唸.
又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦);
都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
careychen
尊榮會員


發表:41
回覆:580
積分:959
註冊:2004-03-03

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-12-12 15:34:25 IP:60.248.xxx.xxx 訂閱
不好意思,說明一下請 st33chen 前輩見諒

使用 Xml 時,如果那個欄位裡有些較特殊的符號時,例如 > < & .... 時會被強制轉變成 http 的那種 Style
例如:
> 變 &gt
< 變 &lt
& 變 &amp

所以在使用時請注意一下,另再說明一下,原本的寫法會有效能上的問題,因此如要使用 XML Path 時,
請改成如下的寫法

[code sql]
Select Type, SubStr(RestaurantNames, 1, Len(RestaurantNames)-1) RestaurantNames
from
(
Select Type from Restaurant Group by Type
) AS A
CROSS APPLY (
SELECT RestaurantName ','
FROM Restaurant AS B
WHERE A.Type = B.Type
FOR XML PATH('')
) D (RestaurantNames)
[/code]


===================引 用 st33chen 文 章===================
再參一腳, 留下記錄當作筆記
mssql 模擬 group_concat 的另一方法

select Type, substr(RestaurantNames,1,len(RestaurantNames)-1) RestaurantNames
from Restaurant AS A
CROSS APPLY (
SELECT RestaurantName ','
FROM Restaurant AS B
WHERE A.Type = B.Type
FOR XML PATH('')
) D (RestaurantNames)
GROUP BY Type, RestaurantNames
------
價值的展現,來自於你用哪一個角度來看待它!!
編輯記錄
careychen 重新編輯於 2008-12-12 15:35:53, 註解 無‧
cindyliu
一般會員


發表:16
回覆:18
積分:6
註冊:2008-09-17

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-12-12 16:54:14 IP:59.120.xxx.xxx 訂閱
st33chen 您好~

我用了你提供的網址裡的這SQL語法是我要的結果...
但是少了條件,我該怎麼套用到我的SQL條件裡呢?
「???」的條件的需要等於最外層的DN_NO與DATA_NO


SELECT A.DN_NO, A.DN_DATE, B.DATA_NO, A.CUSTOM_NO,
(
Select Substr(Sys_Connect_By_Path(REMARK, '、'), 2)
From (Select Rownum Rid, Rownum 1 Next_Rid, REMARK From CHG Where ??? )
Where Rid = (Select Count(*) From CHG Where ???)
Start With Rid = 1 Connect By Prior Next_Rid = Rid

) REMARK_2
FROM DEBTM A, CHG B
WHERE (A.DN_NO=B.DN_NO) AND A.CUSTOM_NO ='A001'
st33chen
尊榮會員


發表:15
回覆:591
積分:1201
註冊:2005-09-30

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-12-13 10:23:31 IP:122.116.xxx.xxx 未訂閱
您好,
我用您下列的例子實測出來的 sql 如下, 其中, type 欄名改為 tp, remark 欄名改為 remarks
(再次呼籲一下, 欄名不要用 可能的保留字) :
with data as (
select tp, remarks,
row_number() over (partition by tp order by tp, remarks) rn,
count(*) over (partition by tp) cnt
from ktop
)
select data.tp, amt, ltrim(sys_connect_by_path(remarks,','),',') remarks
from data, (
select tp, sum(amt) amt from ktop group by tp
) b
where rn = cnt
and data.tp=b.tp
start with rn = 1
connect by prior data.tp = data.tp and prior rn = rn-1
order by data.tp

參考一下

========================================================
補充一下,
我自己測試的結果, 認為, 還是用我在上述連結網頁中提到的建 oracle function 的方法比較好
因為 function 只要建一次, 以後都可在不同的情況下呼叫使用, 比較不用每次不一樣情況都要
花很多腦筋去結構 sql.
只要建一次的 oracle function 如下;
CREATE OR REPLACE FUNCTION matrix (query_in in VARCHAR2) RETURN VARCHAR2 IS
incoming varchar2(4000);
hold_result varchar2(4000);
c sys_refcursor;
Begin
open c for query_in;
loop
fetch c into incoming;
exit when c%notfound;
hold_result := hold_result||','||incoming;
end loop;
return ltrim(hold_result,',');
END;
/
而適用本次例子的 呼叫 sql 如下:
select tp, sum(amt) amt, matrix('select remarks from ktop where tp=' || tp ) remarks from ktop
group by tp
這樣的用法真的就比較接近 mysql 直接把 group_concat 放在 select 子句裏的樣子, 比較直觀.

同理, mssql 部份, 若 careychen 大大能把 mssql 的 那個 function 改成通用型(即不在 function 中寫死哪個 table 哪個 field)
的話, 那是最好不過的.

我工作環境無 mssql, 對 mssql 不熟 (也不喜歡 m.$oft), 所以 mssql 部份我幫不上忙

感恩啦.



===================引 用 cindyliu 文 章===================
請問各位~
這是一份類用明細表
欄位有費用類別、費用代碼、金額、備註....

TYPE CHG_CD AMT REMARK
------- --------------- --------- ----------------
01 1004 250 abcd
02 1210 200 test
01 1005 100
01 1003 150 xyz
02 1221 100 ijk
03 1010 100 efg


這是依費用類別加總,最後產出來的樣子~
TYPE AMT REMARK
------- ---------- ---------------------
01 500 abcdxyz
02 300 testijk
03 100 efg
因為前輩寫的FUNCTION是要傳入一段SQL語法去產出檔案...
目前加總的部分我OK,,,
卡在備註REMARK的地方,SQL要怎麼寫才能達到上面的結果?
請各位高手幫幫忙...感恩^^

補充一下..
因為公司有MSSQL與ORACLE,希望也能有ORACLE的寫法喔...
(目前是ORACLE 比較急需用到) 謝謝^^

------
IS IT WHAT IT IS
我是 李慕白 請倒著唸.
又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦);
都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
編輯記錄
st33chen 重新編輯於 2008-12-13 11:06:04, 註解 無‧
st33chen 重新編輯於 2008-12-13 11:10:19, 註解 無‧
系統時間:2024-11-25 3:41:05
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!