【问题标题】:combining results of two select statements合并两个 select 语句的结果
【发布时间】:2011-02-19 01:50:06
【问题描述】:

我正在使用带有 ASP.NET 和 c# 的 T-SQL,而且我对 SQL 还是很陌生。

我想知道如何合并两个查询的结果

查询 1:

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

查询 2:

 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

任何帮助将不胜感激。 提前致谢

【问题讨论】:

  • ...为什么要把它们结合起来?
  • 你想用两个查询做某事,但无法猜到; “结合”含糊不清。
  • 您的第一个查询应该给出错误:Column 'tableA.Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
  • 请描述您想要实现的目标。例如,就您获得的数据而言,结果会是什么样子。将两个查询放在一起的原因是什么?

标签: sql tsql select


【解决方案1】:

虽然可以合并结果,但我建议不要这样做。

您有两种根本不同类型的查询,它们返回不同数量的行、不同数量的列和不同类型的数据。最好保持原样 - 两个单独的查询。

【讨论】:

  • 它是一个存储过程,它将返回一个 JSON 格式的表(只想进行一个 ajax 调用)。不会有不同的行数和 tableA.ID,并且 tableA.Name 在两个查询中。
  • @ErnieStings:可以进行 JSON 调用,而无需将所有数据放入单个结果集中。如果用户是多个 tableA 的所有者,您当前的策略将传递重复数据。
【解决方案2】:

您可以使用Union。

这将在单独的行中返回查询结果。

首先,您必须确保两个查询返回相同的列。

那么你可以这样做:

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

如前所述,两个查询返回完全不同的数据。如果两个查询都返回可能被认为相似的数据,您可能只想这样做。

所以

您可以使用加入

如果有一些数据在两个查询之间共享。这会将两个查询的结果放入由 id 连接的单行中,这可能是您想要在这里做的更多...

你可以这样做:

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

【讨论】:

    【解决方案3】:

    您可能使用支持公用表表达式 (CTE) 的 Microsoft SQL Server(请参阅http://msdn.microsoft.com/en-us/library/ms190766.aspx),这对查询优化非常友好。所以我建议你我喜欢的建筑:

    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
    

    在使用 CTE 的一些经验之后,您会发现使用 CTE 编写代码非常容易,并且您会对性能感到满意。

    【讨论】:

    • 这可能会给出与原始查询相同的错误。
    • @Mark Byers:不,它必须正常工作(我不考虑我可能犯的写错误)!我只是不确定是否应该使用 INNER JOIN 或 OUTER JOIN 或 UNION 将 GetUserInformation 与 GetNumberOfPlans 结合起来。 CTE 像视图或临时表一样工作,但更有效。如果您将第一个查询的结果保存在临时表中,并将第二个查询的结果保存在第二个表中,您将能够加入这些表。 CTE 做到了这一点,但 SQL 使用现有表上已有的索引。
    • @Mark Byers:绝对可以将 tableA 与 GetUserInformation 和 GetNumberOfPlans 结合起来,就两个子查询的 OUTER JOIN 而言。这将提供最完整的结果集
    猜你喜欢
    • 1970-01-01
    • 2015-08-30
    • 2012-05-19
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2019-08-30
    相关资源
    最近更新 更多