2009-08-31 33 views
5

Tôi cần trả lại nhiều kết quả từ truy vấn phụ và không thể tìm ra kết quả đó. Kết quả cuối cùng sẽ tạo tên người trên trục tung, các hành động khác nhau dựa trên danh mục hành động trên trục hoành. Vì vậy, kết quả cuối cùng trông giống như:Có cách nào để trả về nhiều kết quả với truy vấn phụ không?

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

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


---------- 

Có cách nào để thực hiện điều này trong một truy vấn không?

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

Nếu có nhiều hơn một kết quả được trả về trong subquery mà tôi muốn để có thể hiển thị nó như là một chuỗi dấu phẩy đơn tách ra, hoặc danh sách các hành động vv

Cảm ơn bạn.

Microsoft Sql Server 2005 đang được sử dụng.

+0

Cảm ơn tất cả vì sự giúp đỡ, tôi đánh giá cao thời gian. –

Trả lời

9

tôi sử dụng một User Defined Function cho nhiệm vụ này. Udf tạo một chuỗi phân cách với tất cả các phần tử khớp với các tham số, sau đó bạn gọi udf từ câu lệnh chọn của bạn sao cho bạn kéo một danh sách được phân cách cho mỗi bản ghi trong recordset.

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

Được đánh giá cao, cảm ơn bạn. –

3

bạn cần cung cấp thêm thông tin về cấu trúc bảng của bạn và cách chúng kết hợp với nhau.

đây là một ví dụ chung chung về cách kết hợp nhiều hàng vào một cột duy nhất:

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

Có thể bạn sẽ phải tạo một hàm tổng hợp tùy chỉnh. Microsoft có một bài viết cơ bản về kiến ​​thức với mã mẫu here.

0

Nếu bạn không ngại sử dụng con trỏ, bạn có thể viết chức năng của riêng bạn để thực hiện việc này. Dưới đây là một ví dụ mà sẽ làm việc trên các mẫu 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 

Đây là cách một chức năng như vậy sẽ xuất hiện trong một truy vấn chọn:

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

này là khá trừu tượng và phức tạp. Phản ứng ban đầu của tôi là "truy vấn pivot", nhưng tôi càng xem xét nó (và tại các phản ứng trước đó) tôi càng nghĩ: Bạn có thể vượt qua điều này cho nhóm ứng dụng không? Bạn trả về "cơ sở", và họ viết và áp dụng mã thủ tục làm cho loại vấn đề này trở nên dễ dàng. Chắc chắn, bạn có thể ép nó vào SQL, nhưng điều đó không làm cho nó đúng nơi để thực hiện công việc.

+0

Điều này thực sự cần phải được thực hiện để có được con chó con này vào một báo cáo.Tôi đã hoàn thành nó trong ứng dụng và nó đã được hiển thị tốt khi các yêu cầu thay đổi? Vì vậy, tôi đã điều chỉnh và cần thiết để làm điều đó trong mã do một số hạn chế với phần mềm báo cáo (không phải tùy chỉnh). Tôi rất vui vì ai đó nghĩ rằng đó là một chút rắc rối, bởi vì nó khiến tôi gãi đầu. –

1

Theo truy vấn của bạn thử điều này:

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 đây là cách đơn giản nhất để làm những gì bạn muốn.

EDIT: nếu không có hành động nào trong truy vấn phụ được tìm thấy, kết quả [AdditionalData] sẽ là NULL.

Các vấn đề liên quan