2010-09-17 14 views
6

Estoy usando una base de datos Sybase ASE.
Tengo dos tablas que se parecen:Consulta SQL para "concatenate on join"

Tabla Shops:

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

Tabla Sweets:

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

Quiero escribir una consulta que generaría un resultado que parece:

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

¿Cómo debo hacer eso? Necesito esto para una base de datos Sybase ASE. Intenté la función LIST(), pero recibo un error al respecto. Revisé su documentación, y resulta que esta función no está disponible en la Edición ASE.

Esto probablemente significa que habrá algún "sql dinámico" involucrado (tengo muy poca idea de lo que eso significa). ¿Alguien puede ayudar?

Podría querer ShopId en lugar de ShopName en la tabla de resultados ... No estoy seguro todavía. Supongo que no habrá mucha diferencia. Además, las comas al final en la columna de resultados Sweets no son un problema. Todo lo que quiero es un separador que no sea de espacio en blanco.

+0

Hmm suena como si quisiera una función de agregación de cadenas. No estoy seguro de qué bases de datos hacen eso de forma nativa, pero a veces veo funciones definidas por el usuario para eso (naturalmente que varía de un dmbs a otro). ¿Qué base de datos estas usando? – FrustratedWithFormsDesigner

+1

Estoy usando syabse. – jrharshath

+0

¿Qué errores hizo 'list()' dar? No es que pueda ayudar con los problemas de Sybase, pero alguien más puede reconocer el mensaje de error. – FrustratedWithFormsDesigner

Respuesta

5

Deberá especificar qué DBMS está utilizando.

MySQL's GROUP CONCAT es exactamente lo que necesita.

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

Y Oracle tiene 'wmsys.wm_concat', aunque parece estar indocumentado. Nunca lo he usado, pero lo encontré bastante rápido. Otra solución de Oracle que utiliza 'connect by': http://halisway.blogspot.com/2006/08/oracle-groupconcat-updated-again.html – FrustratedWithFormsDesigner

+0

Necesito hacer esto con el ASE de sybase, así que esto no funcionará para mí. .. Sybase tiene una función LIST() que hace esto, pero no está presente en la edición ASE. – jrharshath

+0

mi google-fu revela este enlace (http://www.projectdmx.com/tsql/rowconcatenate.aspx). ¿Puedes convertir esto al SQL que necesitaré en mi caso? – jrharshath

1

He probado esto en SQL Server, pero espero que también funcione en Sybase. Si no, tal vez te acerque lo suficiente como para resolverlo.

Si creo esta función:

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 

puedo luego ejecutar esta consulta y obtener los resultados que desea:

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

Espero que esto ayude.

+0

Estoy aquí teniendo exactamente el mismo problema. Para mí (Sybase ASE 15.0) eso no funciona. Por algún motivo, solo devuelve la última fila. ¿Es esto una cosa dependiente de la versión? O un ajuste? – Marnix

2

Es una consulta cruzada y es imposible con Sybase ASE en una consulta.

Puede crear un procedimiento almacenado con tabla temporal, llenarlo con el cursor y seleccionar de esta tabla temporal.

1

Desafortunadamente, un método en la respuesta adrift's no funciona con la instrucción select para Sybase ASE, la variable @list no se actualiza para cada fila, funciona solo para la última fila. Pero debido a que la actualización realizada para cada fila y el tamaño de la tabla no es demasiado grande, puede hacerlo con una declaración de actualización. Pequeño ejemplo:

declare @list varchar(500) 

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

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

P.S. En cuanto a mí, el cursor no es buena manera ...

0

Obras en 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 

luego ejecutar ...

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