2010-09-17 11 views
6

Sto utilizzando un database Sybase ASE.
Ho due tabelle che assomigliano:Query SQL per "concatenare in join"

Tabella Shops:

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

Tabella Sweets:

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

Voglio scrivere una query che potrebbe generare un risultato che assomiglia:

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

Come dovrei fare per farlo? Ho bisogno di questo per un database Sybase ASE. Ho provato la funzione LIST(), ma sto ricevendo un errore su questo. Ho controllato la sua documentazione e risulta che questa funzione non è disponibile nell'edizione ASE.

Questo probabilmente significa che saranno coinvolti alcuni "sql dinamici" (non ho idea di cosa significhi). Qualcuno può aiutare?

Potrei volere ShopId invece di ShopName nella tabella dei risultati ... Non so ancora per certo. Immagino che non sarà molto diverso. Inoltre, le virgole finali nella colonna di risultati Sweets non rappresentano un problema. Tutto quello che voglio è un separatore non-spaziatura.

+0

Hmm suona come se si desidera una funzione di aggregazione di stringhe. Non sono sicuro di quali database lo facciano in modo nativo, ma vedo che per il momento vedo funzioni definite dall'utente (naturosamente varia da un dmbs all'altro). che database stai usando? – FrustratedWithFormsDesigner

+1

Sto usando Syabse. – jrharshath

+0

Quali errori ha restituito 'list()'? Non che io possa aiutare con i problemi di Sybase, ma qualcun altro che potrebbe riconoscere il messaggio di errore. – FrustratedWithFormsDesigner

risposta

5

Dovrai specificare quale DBMS stai usando.

MySQL GROUP CONCAT è esattamente quello che ti serve.

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

E Oracle ha 'wmsys.wm_concat', anche se sembra non documentato. Non l'ho mai usato da solo, ma l'ho trovato abbastanza rapidamente. Un'altra soluzione Oracle che utilizza 'connect by': http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html – FrustratedWithFormsDesigner

+0

Ho bisogno di farlo con ASE di sybase, quindi questo non funzionerà per me. .. Sybase ha una funzione LIST() che esegue questa operazione, ma non è presente nell'edizione ASE. – jrharshath

+0

my google-fu rivela questo collegamento (http://www.projectdmx.com/tsql/rowconcatenate.aspx). Puoi convertirlo in SQL di cui ho bisogno nel mio caso? – jrharshath

1

L'ho provato su SQL Server, ma speriamo che funzioni anche su Sybase. In caso contrario, forse ti avvicinerà abbastanza da risolverlo.

Se creo questa funzione:

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 

posso quindi eseguire questa query e ottenere i risultati desiderati:

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

Spero che questo aiuti.

+0

Sono qui con lo stesso identico problema. Per me (Sybase ASE 15.0) che non funziona. Per qualche motivo restituisce solo l'ultima riga. È una cosa dipendente dalla versione? O un'impostazione? – Marnix

2

È una query a campi incrociati ed è impossibile con Sybase ASE in una query.

È possibile creare una procedura memorizzata con la tabella temporanea, riempirla con il cursore e selezionare da questa tabella temporanea.

1

Sfortunatamente, un metodo nella risposta adrift's non funziona con l'istruzione select per Sybase ASE, la variabile @list non si aggiorna per ogni riga, funziona solo per l'ultima riga. Ma poiché l'aggiornamento eseguito per ogni riga e le dimensioni della tabella non sono grandi, è possibile farlo con la dichiarazione di aggiornamento. Piccolo esempio:

declare @list varchar(500) 

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

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

P.S. Per quanto mi riguarda, il cursore non è buon modo ...

0

Lavori in 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 

Quindi eseguire ...

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