2009-08-31 5 views
5

サブクエリから複数の結果を返す必要があり、それを把握することができませんでした。最終的な結果は、縦軸を横切って人物名を生成し、横軸を横切る行動カテゴリーに基づいて様々な行動を生成する。最終結果は次のようになります。サブクエリで複数の結果を返す方法はありますか?

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

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


---------- 

これを単一のクエリで実行する方法はありますか?

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

つ以上の結果がそのサブクエリで返された場合、私は、単一のカンマで区切られた文字列、またはアクションのリストとして表示できるようにしたいと思い、など

はありがとうございます。

Microsoft Sql Server 2005が使用されています。

+0

ありがとうございました。私は助けてくれてありがとう、私は時間を感謝します。 –

答えて

9

私は、このタスクのためのユーザー定義関数を使用します。 udfは、すべての要素がパラメータに一致する区切り文字列を作成し、select文からudfを呼び出して、レコードセット内の各レコードの区切りリストを取得します。

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

ありがとう、ありがとうございます。 –

3

あなたのテーブル構造とそれらがお互いにどのように結合するかについて、より多くの情報を提供する必要があります。ここ

は、単一の列に複数の行を結合に関する一般的な例である:

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

おそらくカスタム集計関数を作成する必要があります。 Microsoftには、サンプルコードhereのナレッジベースの記事があります。

0

カーソルを使用しても構わない場合は、独自の関数を作成してください。ここでAdventureWorksサンプルDB上で動作する例を示します

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 

これは、このような機能は、選択クエリに表示される方法です:

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

これはかなり抽象的かつ複雑です。私の最初の反応は「ピボットクエリー」でしたが、私はそれを見て、より多くのものを考えました。これをアプリケーションチームに渡すことはできますか?あなたは "ベース"を返し、この種の問題を簡単にする手続き型コードを記述して適用します。確かに、それをSQLに絞ることはできますが、それはその作業を行うのに適切な場所にはなりません。

+0

この子犬を報告書に入れるには、実際にこれを行う必要がありました。私はそれをアプリケーションで完成させましたが、要件が変わったときにはうまく表示されていましたか?だから私は調整し、レポートソフトウェア(カスタムではない)のいくつかの制限のためにコードでそれを行う必要があった。私は頭が傷ついていたので、他の誰かが面倒なことだと思ってうれしいです。 –

1

クエリによれば、これを試してみてください。

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] 

が、これはあなたが欲しいものを行うための最も簡単な方法だと思います。

EDIT:サブクエリにアクションがない場合、[AdditionalData]の結果はNULLになります。