2010-09-17 54 views
6

我使用的是的Sybase ASE數據庫
我看起來像兩個表:SQL查詢「串聯上加入」

Shops

--------------------- 
| ShopName | ShopID | 
--------------------- 
| Sweetie | 1  | 
| Candie | 2  | 
| Sugarie | 3  | 
--------------------- 

Sweets

---------------------- 
| SweetName | ShopID | 
---------------------- 
| lolly  | 1  | 
| redlolly | 1  | 
| greenloly | 1  | 
| taffy  | 2  | 
| redtaffy | 2  | 
| bluetaffy | 2  | 
| choco  | 3  | 
| mintchoco | 3  | 
| milkchoco | 3  | 
| gummybees | 3  | 
---------------------- 

我想寫一個查詢,會產生一個結果,看起來像:

----------------------------------------------------- 
| ShopName | Sweets         | 
----------------------------------------------------- 
| Sweetie | lolly, redlolly, greenlolly   | 
| Candie | taffy, redtaffy, bluetaffy    | 
| Sugarie | choco, mintchoco, milkchoco, gummybees | 
----------------------------------------------------- 

我應該怎麼做?我需要這個用於Sybase ASE數據庫。我嘗試了LIST()函數,但我得到一個錯誤。我檢查了它的文檔,結果證明,這個函數在ASE版本中不可用。

這可能意味着會有一些「動態SQL」參與(我很少知道這意味着什麼)。誰能幫忙?

我可以想要ShopId而不是ShopName在結果表中......我還不確定。我想這不會有太大的區別。而且,Sweets結果列中的尾隨逗號不是問題。我只想要一個非空白分隔符。

+0

嗯聽起來像你想要一個字符串聚合函數。我不確定哪些數據庫能夠在本地執行此操作,但是我看到有時會看到用戶定義的函數(當然,這種函數從一個dmbs到另一個dmbs不等)。你使用的是哪個數據庫? – FrustratedWithFormsDesigner 2010-09-17 18:08:44

+1

我正在使用syabse。 – jrharshath 2010-09-17 18:29:26

+0

list()給出了什麼錯誤?並不是說我可以幫助解決Sybase問題,而是能夠識別錯誤消息的其他人。 – FrustratedWithFormsDesigner 2010-09-17 18:57:10

回答

5

您必須指定您正在使用的DBMS。

MySQL的GROUP CONCAT正是你所需要的。

SELECT ShopName, GROUP_CONCAT(SweetName SEPARATOR ", ") 
FROM Shops a 
JOIN Sweets b 
ON a.ShopID = b.ShopID 
GROUP BY ShopName 
+2

而Oracle有'wmsys.wm_concat',雖然它似乎沒有記錄。我從來沒有用過它,但發現它很快。另一個使用'connect by'的Oracle解決方案:http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html – FrustratedWithFormsDesigner 2010-09-17 18:12:50

+0

我需要用sybase ASE來做到這一點,所以這對我不起作用。 Sybase確實有這樣做的LIST()函數,但它不存在於ASE版本中。 – jrharshath 2010-09-17 18:50:47

+0

我的google-fu顯示此鏈接(http://www.projectdmx.com/tsql/rowconcatenate.aspx)。你能把它轉換成我需要的SQL嗎? – jrharshath 2010-09-17 20:23:48

1

我在SQL Server上測試了它,但希望它也能在Sybase上工作。如果沒有,也許它會讓你足夠接近解決它。

如果我創建這個函數:

CREATE FUNCTION SweetsList(@shopID int) 
RETURNS varchar(500) 
AS 
BEGIN 

    DECLARE @list varchar(500) 

    SELECT @list = COALESCE(@list+', ','') + SweetName 
    FROM Sweets 
    WHERE ShopID = @shopID 

    RETURN @list 
END 

然後我就可以執行這個查詢,並得到你想要的結果:

SELECT ShopName, dbo.SweetsList(ShopID) AS Sweets 
FROM Shops 

希望這有助於。

+0

我在這裏有完全相同的問題。對我來說(Sybase ASE 15.0)不起作用。出於某種原因,它只返回最後一行。這是一個版本依賴的東西?或者一個設置? – Marnix 2012-03-17 13:31:11

2

這是一個交叉表查詢,在一個查詢中對於Sybase ASE是不可能的。

您可以創建臨時表的存儲過程,用光標填充它,並從該臨時表中選擇。

1

不幸的是,在adrift's答案的方法不用於Sybase ASE的SELECT語句工作,可變@list不爲每一行更新,它僅適用於最後一排。但是因爲更新對每行和每個表的大小執行不會很大,所以可以使用update語句來完成。小例子:

declare @list varchar(500) 

    update Sweets 
    set @list = @list + SweetName + ', ' 
    where ShopID = 1 

    select SUBSTRING(@list, 1, Len(@list) - 2) 

P.S.至於我,光標是不是好辦法...

0

作品在Sybase ASE的...

CREATE FUNCTION SweetsList(@SN varchar(10)) 
returns varchar(255) 
AS 
DECLARE @SwNList varchar(255) 
DECLARE @FetchSwN varchar(55) 
DECLARE @Status INT, @Error INT 

DECLARE ListCurs CURSOR FOR 
SELECT SweetName 
    FROM Sweets AS SW 
JOIN Shops AS SH 
    ON SH.ShopID = SW.ShopID 
WHERE SH.ShopName = @SN 
FOR READ ONLY 

OPEN ListCurs 
SELECT @Status = 0 
WHILE @Status = 0 
BEGIN 
    FETCH ListCurs INTO @FetchSwN 

    SELECT @Status = @@SQLSTATUS 

    IF @Status = 0 
    BEGIN 
     SELECT @SwNList = CASE WHEN @SwNList IS NULL THEN '' ELSE @SwNList + ', ' END + @FetchSwN 
    END 
END 
CLOSE ListCurs 
RETURN (@SwNList) 
go 

然後執行...

SELECT ShopName, dbo.SweetsList(ShopName) AS Sweets FROM Shops