2010-05-13 53 views
10

Tôi đang sử dụng T-SQL với ASP.NET và C# và tôi khá mới đối với SQL.kết hợp kết quả của hai câu lệnh chọn

tôi đã tự hỏi làm thế nào tôi có thể kết hợp các kết quả của hai truy vấn

Query1:

SELECT tableA.Id, tableA.Name, [tableB].Username AS Owner, [tableB].ImageUrl, [tableB].CompanyImageUrl, COUNT(tableD.UserId) AS NumberOfUsers 
FROM tableD RIGHT OUTER JOIN 
     [tableB] INNER JOIN 
     tableA ON [tableB].Id = tableA.Owner ON tableD.tableAId = tableA.Id 
GROUP BY tableA.Name, [tableB].Username, [tableB].ImageUrl, [tableB].CompanyImageUrl 

Query2:

SELECT tableA.Id, tableA.Name, COUNT([tableC].Id) AS NumberOfPlans 
FROM [tableC] RIGHT OUTER JOIN 
      tableA ON [tableC].tableAId = tableA.Id 
GROUP BY tableA.Id, tableA.Name 

Bất kỳ trợ giúp sẽ được nhiều đánh giá cao . Cảm ơn trước

+2

... tại sao bạn muốn kết hợp chúng? –

+0

Bạn muốn làm điều gì đó với hai truy vấn, nhưng không thể đoán được điều gì; 'kết hợp' là nhiều để mơ hồ. – Smandoli

+0

Truy vấn đầu tiên của bạn sẽ đưa ra một lỗi: 'Cột 'tableA.Id' không hợp lệ trong danh sách chọn vì nó không được chứa trong hàm tổng hợp hoặc mệnh đề GROUP BY.' –

Trả lời

26

Bạn có thể sử dụng Union.

Điều này sẽ trả lại kết quả của các truy vấn trong các hàng riêng biệt.

Trước tiên, bạn phải đảm bảo rằng cả hai truy vấn đều trả về các cột giống nhau.

Sau đó, bạn có thể làm:

SELECT tableA.Id, tableA.Name, [tableB].Username AS Owner, [tableB].ImageUrl, [tableB].CompanyImageUrl, COUNT(tableD.UserId) AS Number 
FROM tableD 
RIGHT OUTER JOIN [tableB] 
INNER JOIN tableA ON [tableB].Id = tableA.Owner ON tableD.tableAId = tableA.Id 
GROUP BY tableA.Name, [tableB].Username, [tableB].ImageUrl, [tableB].CompanyImageUrl 

UNION 

SELECT tableA.Id, tableA.Name, '' AS Owner, '' AS ImageUrl, '' AS CompanyImageUrl, COUNT([tableC].Id) AS Number 
FROM 
[tableC] 
RIGHT OUTER JOIN tableA ON [tableC].tableAId = tableA.Id GROUP BY tableA.Id, tableA.Name 

Như đã đề cập, cả hai truy vấn trả về dữ liệu hoàn toàn khác nhau. Bạn có thể chỉ muốn làm điều này nếu cả hai truy vấn trả về dữ liệu có thể được coi là tương tự.

SO

Bạn có thể sử dụng một tham

Nếu có một số dữ liệu được chia sẻ giữa hai truy vấn. Điều này sẽ đưa các kết quả của cả hai truy vấn vào một hàng duy nhất sự tham gia của các id, mà có lẽ nhiều hơn những gì bạn muốn được làm gì ở đây ...

Bạn có thể làm:

SELECT tableA.Id, tableA.Name, [tableB].Username AS Owner, [tableB].ImageUrl, [tableB].CompanyImageUrl, COUNT(tableD.UserId) AS NumberOfUsers, query2.NumberOfPlans 
FROM tableD 
RIGHT OUTER JOIN [tableB] 
INNER JOIN tableA ON [tableB].Id = tableA.Owner ON tableD.tableAId = tableA.Id 


INNER JOIN 
    (SELECT tableA.Id, COUNT([tableC].Id) AS NumberOfPlans 
    FROM [tableC] 
    RIGHT OUTER JOIN tableA ON [tableC].tableAId = tableA.Id 
    GROUP BY tableA.Id, tableA.Name) AS query2 
ON query2.Id = tableA.Id 

GROUP BY tableA.Name, [tableB].Username, [tableB].ImageUrl, [tableB].CompanyImageUrl 
6

Mặc dù có thể kết hợp các kết quả, tôi khuyên bạn không nên làm như vậy.

Bạn có hai loại truy vấn cơ bản khác nhau trả về một số hàng khác nhau, một số cột khác nhau và các loại dữ liệu khác nhau. Nó sẽ là tốt nhất để lại nó như nó là - hai truy vấn riêng biệt.

+0

của nó cho một thủ tục được lưu trữ mà sẽ trả về một bảng duy nhất trong JSON (chỉ muốn thực hiện một cuộc gọi ajax). Sẽ không có một số hàng khác nhau và tableA.ID và tableA.Name nằm trong cả hai truy vấn. – ErnieStings

+0

@ErnieStings: Có thể thực hiện cuộc gọi JSON mà không phải đặt tất cả dữ liệu của bạn vào một tập hợp kết quả duy nhất. Chiến lược hiện tại của bạn sẽ chuyển dữ liệu trùng lặp nếu người dùng là chủ sở hữu cho nhiều tableA. –

5

Có lẽ bạn sử dụng Microsoft SQL Server hỗ trợ các biểu thức bảng chung (CTE) (xem http://msdn.microsoft.com/en-us/library/ms190766.aspx) rất thân thiện với việc tối ưu hóa truy vấn. Vì vậy, tôi đề nghị bạn xây dựng ưu tiên của tôi:

WITH GetNumberOfPlans(Id,NumberOfPlans) AS (
    SELECT tableA.Id, COUNT(tableC.Id) 
    FROM tableC 
     RIGHT OUTER JOIN tableA ON tableC.tableAId = tableA.Id 
    GROUP BY tableA.Id 
),GetUserInformation(Id,Name,Owner,ImageUrl, 
        CompanyImageUrl,NumberOfUsers) AS (
    SELECT tableA.Id, tableA.Name, tableB.Username AS Owner, tableB.ImageUrl, 
     tableB.CompanyImageUrl,COUNT(tableD.UserId),p.NumberOfPlans 
    FROM tableA 
     INNER JOIN tableB ON tableB.Id = tableA.Owner 
     RIGHT OUTER JOIN tableD ON tableD.tableAId = tableA.Id 
    GROUP BY tableA.Name, tableB.Username, tableB.ImageUrl, tableB.CompanyImageUrl 
) 
SELECT u.Id,u.Name,u.Owner,u.ImageUrl,u.CompanyImageUrl 
    ,u.NumberOfUsers,p.NumberOfPlans 
FROM GetUserInformation AS u 
    INNER JOIN GetNumberOfPlans AS p ON p.Id=u.Id 

Sau khi một số kinh nghiệm với CTE bạn sẽ thấy rất dễ viết mã bằng CTE và bạn sẽ hài lòng với hiệu suất.

+0

Điều này có thể sẽ cung cấp cho cùng một lỗi như truy vấn ban đầu. –

+0

@Mark Byers: Không, nó ** phải ** làm việc mà không có lỗi (Tôi không xem xét việc viết các lỗi mà tôi có thể thực hiện)! Tôi chỉ không chắc liệu có nên sử dụng INNER JOIN hay OUTER JOIN hay UNION để kết hợp GetUserInformation với GetNumberOfPlans hay không. CTE hoạt động như một VIEW hoặc bảng tạm thời, nhưng hiệu quả hơn nhiều. Nếu bạn lưu kết quả của truy vấn đầu tiên trong bảng tạm thời và kết quả của truy vấn thứ hai trong bảng thứ hai, bạn sẽ có thể THAM GIA các bảng. CTE làm điều này, nhưng SQL sử dụng các chỉ mục hiện có trên các bảng hiện có. – Oleg

+0

@Mark Byers: Để chắc chắn bạn có thể kết hợp tableA với GetUserInformation và GetNumberOfPlans đối với OUTER JOIN trên cả hai truy vấn phụ. Điều này sẽ cho kết quả đầy đủ nhất – Oleg

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