2009-08-31 20 views
5

Necesito devolver resultados múltiples de una subconsulta y no he podido resolverlo. El resultado final producirá el nombre de las personas en el eje vertical, varias acciones basadas en una categoría de acción en el eje horizontal. Entonces, el resultado final se ve así:¿Hay alguna forma de devolver resultados múltiples con una subconsulta?

---------- 
**NAME   CATEGORY 1    CATEGORY 2** 

Smith, John  Action 1, Action 2  Action 1, Action 2, Action 3 


---------- 

¿Hay alguna manera de hacerlo en una sola consulta?

select 
    name, 
    (select action from actionitemtable where actioncategory = category1 and contact = contactid) 
from 
    contact c 
    inner join actionitemtable a 
    on c.contactid = a.contactid 

Si más de un resultado que se devuelve en subconsulta Me gustaría ser capaz de mostrar como una cadena única separada por comas, o una lista de acciones, etc.

Gracias.

Microsoft Sql Server 2005 se está utilizando.

+0

Gracias a todos por la ayuda, agradezco el tiempo. –

Respuesta

9

utilizo una función definida por el usuario para esta tarea. El udf crea una cadena delimitada con todos los elementos que coinciden con los parámetros, luego llama al udf de su declaración de selección de modo que extrae una lista delimitada para cada registro en el conjunto de registros.

CREATE FUNCTION dbo.ud_Concat(@actioncategory int, @contactid int) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    DECLARE @sOutput VARCHAR(8000) 
    SET @sOutput = '' 

    SELECT @sOutput = COALESCE(@sOutput, '') + action + ', ' 
    FROM dbo.actionitemtable 
    WHERE [email protected] AND [email protected] 
    ORDER BY action 

    RETURN @sOutput 
END 

SELECT 
    name, 
    dbo.ud_Concat(category1, contactid) as contactList 
FROM contact c 
INNER JOIN actionitemtable a ON c.contactid = a.contactid 
+0

Muy apreciado, gracias. –

3

necesita dar más información sobre la estructura de su mesa y cómo se unen entre sí.

aquí es un ejemplo genérico acerca de la combinación de múltiples filas en una sola columna:

declare @table table (name varchar(30) 
        ,ID int 
        ,TaskID char(3) 
        ,HoursAssigned int 
        ) 

insert into @table values ('John Smith' ,4592 ,'A01' ,40) 
insert into @table values ('Matthew Jones',2863 ,'A01' ,20) 
insert into @table values ('Jake Adams' ,1182 ,'A01' ,100) 
insert into @table values ('Matthew Jones',2863 ,'A02' ,50) 
insert into @table values ('Jake Adams' ,2863 ,'A02' ,10) 


SELECT DISTINCT 
    t1.TaskID 
     ,SUBSTRING(
        replace(
          replace(
            (SELECT 
             t2.Name 
             FROM @Table AS t2 
             WHERE t1.TaskID=t2.TaskID 
             ORDER BY t2.Name 
             FOR XML PATH('')) 
           ,'</NAME>','') 
         ,'<NAME>',', ') 
       ,3,2000) AS PeopleAssigned 
    FROM @table AS t1 

SALIDA:

TaskID PeopleAssigned 
------ -------------------------------------- 
A01 Jake Adams, John Smith, Matthew Jones 
A02 Jake Adams, Matthew Jones 

(2 row(s) affected) 
0

Es probable que deba crear una función de agregado personalizada. Microsoft tiene un artículo de la base de conocimiento con código de ejemplo here.

0

Si no le molesta usar cursores, puede escribir su propia función para hacer esto. He aquí un ejemplo que funciona en la muestra DB Adventureworks:

CREATE FUNCTION CommaFunctionSample 
(
    @SalesOrderID int 
) 
RETURNS varchar(max) 
AS 
BEGIN 

DECLARE OrderDetailCursor CURSOR LOCAL FAST_FORWARD 
FOR 
SELECT SalesOrderDetailID 
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID = @SalesOrderID 

DECLARE @SalesOrderDetailID INT 

OPEN OrderDetailCursor 

FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID 
DECLARE @Buffer varchar(max) 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    IF @Buffer IS NOT NULL SET @Buffer = @Buffer + ',' 
    ELSE SET @Buffer = '' 

    SET @Buffer = @Buffer + CAST(@SalesOrderDetailID AS varchar(12)) 

    FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID 
END 

CLOSE OrderDetailCursor 
DEALLOCATE OrderDetailCursor 

RETURN @Buffer 
END 

Este es el aspecto que tendría una función de este tipo en una consulta de selección:

SELECT AccountNumber, dbo.CommaFunctionSample(SalesOrderID) 
FROM Sales.SalesOrderHeader 
1

Esto es bastante abstracto y complejo. Mi reacción inicial fue "consulta pivote", pero cuanto más lo miraba (y en las respuestas anteriores), más pensaba: ¿Se lo puedes pasar al equipo de aplicaciones? Usted devuelve la "base" y escriben y aplican el código de procedimiento que hace que este tipo de problema sea muy fácil. Claro, puede exprimirlo en SQL, pero eso no lo convierte en el lugar correcto para hacer el trabajo.

+0

Esto realmente tenía que hacerse para poder incluir a este cachorro en un informe.Lo logré en la aplicación y se mostró bien cuando cambiaron los requisitos. Así que me estaba ajustando y necesitaba hacerlo en el código debido a algunas restricciones con el software de informes (no personalizado). Me alegro de que alguien más pensara que también era un poco molesto, porque me tenía rascándome la cabeza. –

1

De acuerdo con la consulta intente esto:

SELECT [Name], 
     STUFF(
     (
      SELECT ' ,' + [Action] 
      FROM [AactionItemTable] 
      WHERE [ActionCategory] = category1 
        AND [Contact] = contactid 
      FOR XML PATH('') 
     ), 1, 2, ''     
     ) AS [AdditionalData] 
FROM [Contact] C 
     INNER JOIN [ActionItemTable] A 
     ON C.[ContactId] = A.[ContactId] 

que esta es la forma más sencilla de hacer lo que quiera.

EDIT: si no hay acción en la subconsulta encontrado, el resultado será [AdditionalData]NULL.

Cuestiones relacionadas