2009-08-31 16 views
5

Potrzebuję zwrócić wiele wyników z podzapytania i nie mogłem tego rozgryźć. Wynik końcowy będzie generował nazwiska osób na osi pionowej, różne działania oparte na kategorii działań na osi poziomej. Tak więc wynik końcowy wygląda następująco:Czy istnieje sposób na zwrócenie wielu wyników z podzapytaniem?

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

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


---------- 

Czy istnieje sposób, aby zrobić to w jednym zapytaniu?

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

Jeśli więcej niż jeden wynik jest zwracany w tym podzapytaniu Chciałbym być w stanie wyświetlić go jako pojedynczy ciąg oddzielonych przecinkami lub listy działań, itp

dziękuję.

Serwer Microsoft Sql 2005 jest używany.

+0

Dziękuję wszystkim za pomoc, doceniam czas. –

Odpowiedz

9

używam użytkownika określonej funkcji dla tego zadania. Udf tworzy rozdzielony ciąg znaków z wszystkimi elementami pasującymi do parametrów, następnie wywołujesz udf z instrukcji select tak, że wyciągasz rozdzielaną listę dla każdego rekordu w zestawie rekordów.

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

Bardzo doceniane, dziękuję. –

3

Musisz podać więcej informacji o strukturze stołu i sposobie łączenia się ze sobą.

tutaj jest ogólnym przykładem o łączenie wielu wierszy do pojedynczej kolumny:

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 

WYJŚCIE:

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

(2 row(s) affected) 
0

Prawdopodobnie będziesz musiał utworzyć niestandardową funkcję agregującą. Firma Microsoft ma artykuł bazy wiedzy z przykładowym kodem here.

0

Jeśli nie masz nic przeciwko używaniu kursorów, możesz napisać własną funkcję, aby to zrobić. Oto przykład, który będzie działał na próbki 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 

To jak taka funkcja wydaje się kwerendę wybierającą:

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

Jest to dość abstrakcyjne i złożone. Moja pierwsza reakcja była "kwerendą przestawną", ale im więcej na nią patrzyłem (i we wcześniejszych odpowiedziach) tym bardziej myślałem: czy możesz przekazać tę wiadomość zespołowi aplikacyjnemu? Zwracasz "bazę", a oni piszą i stosują kod proceduralny, który sprawia, że ​​ten rodzaj problemu jest bardzo szybki. Oczywiście, możesz wycisnąć go do SQL, ale to nie czyni tego właściwego miejsca do pracy.

+0

To musiało być zrobione, aby ten szczeniak znalazł się w raporcie.Miałem to zrobione w aplikacji i wyświetlało się dobrze, gdy zmieniły się wymagania? Więc dostosowywałem i potrzebowałem zrobić to w kodzie z powodu pewnych ograniczeń z oprogramowaniem raportującym (nie niestandardowym). Cieszę się, że ktoś jeszcze pomyślał, że to też trochę kłopotliwe, ponieważ kazałem mi drapać się po głowie. –

1

Według zapytaniu spróbuj tego:

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] 

Guess jest to najprostszy sposób, aby robić to, co chcesz.

EDIT: jeśli nie ma działania w podzapytaniu znaleźć, wynik [AdditionalData] będzie NULL.

Powiązane problemy