Объединение результатов двух операторов select
Я использую T-SQL с ASP.NET, и С#, и я довольно новичок в SQL.
Мне было интересно, как я мог бы объединить результаты двух запросов
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
Любая помощь будет высоко оценена.
Спасибо заранее
Ответы
Ответ 1
Вы можете использовать Союз.
Это приведет к возврату результатов запросов в отдельных строках.
Сначала вы должны убедиться, что оба запроса возвращают одинаковые столбцы.
Затем вы можете сделать:
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
Как уже упоминалось, оба запроса возвращают совсем другие данные. Вероятно, вы захотите сделать это только в том случае, если оба запроса возвращают данные, которые можно считать похожими.
SO
Вы можете использовать Join
Если есть некоторые данные, которые разделяются между двумя запросами. Это поместит результаты обоих запросов в одну строку, соединенную с 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
Ответ 2
Хотя можно комбинировать результаты, я бы посоветовал не делать этого.
У вас есть два принципиально разных типа запросов, которые возвращают различное количество строк, другое количество столбцов и различные типы данных. Было бы лучше оставить его как есть - два отдельных запроса.
Ответ 3
Возможно, вы используете Microsoft SQL Server, который поддерживает Common Table Expressions (CTE) (см. 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, и вы будете довольны производительностью.