2009-08-31 11 views
5

Ich musste mehrere Ergebnisse von einer Unterabfrage zurückgeben und konnte es nicht herausfinden. Das Endergebnis wird den Namen der Person auf der vertikalen Achse, verschiedene Aktionen basierend auf einer Aktionskategorie auf der horizontalen Achse, ergeben. So sieht das Endergebnis aus:Gibt es eine Möglichkeit, mehrere Ergebnisse mit einer Unterabfrage zurückzugeben?

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

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


---------- 

Gibt es eine Möglichkeit, dies in einer einzigen Abfrage zu tun?

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

Wenn mehr als ein Ergebnis in dieser Unterabfrage zurückgegeben wird, ich möchte es anzeigen können als ein einziges Komma getrennte Zeichenfolge oder Liste von Aktionen, usw.

Danke.

Microsoft Sql Server 2005 wird verwendet.

+0

Vielen Dank für die Hilfe, ich schätze die Zeit. –

Antwort

9

ich für diese Aufgabe eine benutzerdefinierte Funktion verwenden. Das udf erstellt eine Zeichenfolge mit Trennzeichen, bei der alle Elemente den Parametern entsprechen. Anschließend rufen Sie das udf-Objekt in Ihrer SELECT-Anweisung so auf, dass Sie eine getrennte Liste für jeden Datensatz im Re-Cord-Set ziehen.

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

Vielen Dank, danke. –

3

Sie müssen mehr Informationen über Ihre Tabellenstruktur geben und wie sie sich miteinander verbinden.

hier ist ein allgemeines Beispiel über mehrere Zeilen in einer einzigen Spalte Kombination:

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 

OUTPUT:

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

(2 row(s) affected) 
0

Sie müssen wahrscheinlich eine benutzerdefinierte Aggregatfunktion erstellen. Microsoft hat einen Knowledge Base-Artikel mit Beispielcode here.

0

Wenn es Ihnen nichts ausmacht, Cursor zu verwenden, können Sie Ihre eigene Funktion schreiben, um dies zu tun. Hier ist ein Beispiel, das auf der Adventureworks-Beispiel DB arbeiten:

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 

Dies ist, wie eine solche Funktion in einer Auswahlabfrage erscheinen würde:

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

Diese hübsche abstrakt und komplex ist. Meine erste Reaktion war "Pivot Query", aber je mehr ich es betrachtete (und bei den früheren Antworten), desto mehr dachte ich: Können Sie dieses an das Anwendungsteam weitergeben? Sie geben die "Basis" zurück, und sie schreiben und wenden den prozeduralen Code an, der diese Art von Problem zu einem Kinderspiel macht. Sicher, Sie können es in SQL hineinquetschen, aber das macht es nicht den richtigen Ort, um die Arbeit zu machen.

+0

Dies musste tatsächlich getan werden, um diesen Welpen in einen Bericht zu bringen.Ich hatte es in der Anwendung erreicht und es zeigte sich gut, wenn sich die Anforderungen änderten? Also habe ich Anpassungen vorgenommen und musste es aufgrund einiger Einschränkungen mit der Berichtssoftware tun (nicht benutzerdefiniert). Ich bin froh, dass jemand anderes es auch für ein bisschen mühsam gehalten hat, weil ich am Kopf kratze. –

1

Nach Ihrer Anfrage versuchen Sie dies:

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] 

Raten dies der einfachste Weg ist, zu tun, was Sie wollen.

EDIT: wenn es keine Aktion in der Unterabfrage gefunden ist, das [AdditionalData] Ergebnis NULL sein wird.

Verwandte Themen