¿Cómo devolver múltiples valores en una columna (T-SQL)?


Tengo una tabla UserAliases (UserId, Alias) con múltiples alias por usuario. Necesito consultarlo y devolver todos los alias de un usuario dado, el truco es devolverlos todos en una columna.

Ejemplo:

UserId/Alias  
1/MrX  
1/MrY  
1/MrA  
2/Abc  
2/Xyz

Quiero el resultado de la consulta en el siguiente formato:

UserId/Alias  
1/ MrX, MrY, MrA  
2/ Abc, Xyz

Gracias.

Estoy usando SQL Server 2005.

P. s. consulta T-SQL real sería apreciada:)

Author: marc_s, 2008-09-23

9 answers

Puede usar una función con COALESCE.

CREATE FUNCTION [dbo].[GetAliasesById]
(
    @userID int
)
RETURNS varchar(max)
AS
BEGIN
    declare @output varchar(max)
    select @output = COALESCE(@output + ', ', '') + alias
    from UserAliases
    where userid = @userID

    return @output
END

GO

SELECT UserID, dbo.GetAliasesByID(UserID)
FROM UserAliases
GROUP BY UserID

GO
 55
Author: Scott Nichols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-23 18:56:29

Bueno... Veo que ya se ha aceptado una respuesta... pero creo que deberías ver otras soluciones de todos modos:

/* EXAMPLE */
DECLARE @UserAliases TABLE(UserId INT , Alias VARCHAR(10))
INSERT INTO @UserAliases (UserId,Alias) SELECT 1,'MrX'
     UNION ALL SELECT 1,'MrY' UNION ALL SELECT 1,'MrA'
     UNION ALL SELECT 2,'Abc' UNION ALL SELECT 2,'Xyz'

/* QUERY */
;WITH tmp AS ( SELECT DISTINCT UserId FROM @UserAliases )
SELECT 
    LEFT(tmp.UserId, 10) +
    '/ ' +
    STUFF(
            (   SELECT ', '+Alias 
                FROM @UserAliases 
                WHERE UserId = tmp.UserId 
                FOR XML PATH('') 
            ) 
            , 1, 2, ''
        ) AS [UserId/Alias]
FROM tmp

/* -- OUTPUT
  UserId/Alias
  1/ MrX, MrY, MrA
  2/ Abc, Xyz    
*/
 15
Author: leoinfo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-15 14:00:05

Echa un vistazo a este hilo que ya está en StackOverflow, convenientemente te da un ejemplo de T-SQL.

 3
Author: Mike McAllister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:57

Esta es una de las formas más rápidas y simples de hacer lo que necesita sin la necesidad de un UDF: http://weblogs.sqlteam.com/mladenp/archive/2007/06/01/60220.aspx

Hay otra forma de usar una tabla de números que es más rápida para conjuntos de datos realmente grandes, pero no creo que necesites eso.

 3
Author: Mladen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-23 22:17:36

Mi jefe escribió un artículo sobre este camino en 2003: Concatenación con COALESCE

 2
Author: Ryan Rinaldi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-23 18:53:36
DECLARE @Str varchar(500)

SELECT @Str=COALESCE(@Str,'') + CAST(ID as varchar(10)) + ','
FROM dbo.fcUser

SELECT @Str
 1
Author: Tushar Maru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-08 01:43:10

Puede recorrer las filas con un cursor y anexar un campo en una tabla temporal, o puede usar la función COALESCE para concatenar los campos.

 0
Author: Eric Z Beard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-05 18:28:02

Lo siento, lea mal la pregunta la primera vez. Puedes hacer algo como esto:

declare @result varchar(max)

--must "initialize" result for this to work
select @result = ''

select @result = @result + alias
FROM aliases
WHERE username='Bob'
 0
Author: CodeRedick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-04 13:01:25

Group_concat() suena como lo que estás buscando.

Http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

Ya que estás en mssql, acabo de buscar en Google "group_concat mssql" y encontré un montón de hits para recrear la funcionalidad group_concat. aquí está uno de los éxitos que encontré:

Http://www.stevenmapes.com/index.php?/archives/23-Recreating-MySQL-GROUP_CONCAT-In-MSSQL-Cross-Tab-Query.html

 -1
Author: gehsekky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-23 18:45:28