我有三个查询已经处于我的SQL知识的最高点(Microsoft SQL 2005,如果这很重要) - 现在我需要将它们组合成一个查询,其中包含单行上的所有值。
我的实际查询如下,但我认为如果我在这里提供一个简单版本会更容易:
查询一:
-- Provides School District summary based on a CountyID
SELECT DistrictID, Count(Schools) as NumberofSchools
FROM Schools
WHERE (CountyID = 207)
GROUP BY DistrictID
查询一个示例输出:
DistrictID | NumberofSchools
345 | 26
567 | 17
211 | 9
查询二:
-- Summarizes Activity from our Contact Manager (GoldMine)
SELECT DistrictID, Count(Contacts) as NumberofContacts, MAX(Contact) as LastActivity
FROM ContactManager JOINED WITH CONTACT MANAGER TABLES
WHERE (CountyID = 207)
GROUP BY DistrictID
查询两个样本输出:
DistrictID | NumberofContacts | LastActivity
345 | 29 | Nov 12, 2010
567 | 31 | Dec 5, 2010
211 | 4 | Oct 9, 2010
查询三:
-- Summarizes data from our Opt-In Email Newsletter
SELECT DistrictID, Count(EmailSubscribers) AS NumberofSubscribers, MAX(Date) AS LastSent
FROM SubscribeList JOINED WITH Schools Tables
WHERE (CountyID = 207)
GROUP BY DistrictID
查询三个示例输出:
DistrictID | NumberofSubscribers | LastSent
345 | 2 | Sep 4, 2010
567 | 3 | Oct 22, 2010
211 | 1 | NULL
我尝试使用父SELECT语句创建一个巨大的UNION,(来自this weblink的详细信息,并为每个数据集引入SELECT NULL AS MissingColumnName)但它真的很丑 - 并且不会返回所有内容在一排。
我正在寻找这样的结果:
DistrictID | NumberofSchools | NumberofContacts | LastActivity | NumberofSubscribers | LastSent
345 | 26 | 29 | Nov 12, 2010 | 2 | Sep 4, 2010
567 | 17 | 31 | Dec 5, 2010 | 3 | Oct 22, 2010
211 | 9 | 4 | Oct 9, 2010 | 1 | NULL
我该如何使这项工作? (如果你很好奇,我加入的真实问题就在下面)
感谢您的帮助!,
Russell Schutte
尽我所能清理这些 - 对不起,他们显示不是很好。 (这些也可能存在问题 - 它们在我的SQL知识中处于领先地位,但到目前为止,结果看似准确。): - )
查询一:
SELECT
institutionswithzipcodesadditional_1.DistrictID, institutionswithzipcodesadditional_1.InstitutionName, institutionswithzipcodesadditional_1.Latitude, institutionswithzipcodesadditional_1.Longitude,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (4, 5, 6, 7, 8, 14, 15, 16, 20) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS OthersEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (4, 5, 6, 7, 8, 14, 15, 16, 20) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS OthersCount,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (13) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS K12SchoolsEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (13) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS K12SchoolsCount,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (12) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS HighSchoolsEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (12) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS HighSchoolsCount,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (10, 11) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS MiddleSchoolsEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (10, 11) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS MiddleSchoolsCount,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (9) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS ElementariesEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (9) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS ElementariesCount,
SUM(CASE WHEN institutionswithzipcodesadditional.LevelID IN (4, 5, 6, 7, 8, 14, 15, 16, 20, 13, 12, 10, 11, 9) THEN institutionswithzipcodesadditional.Enrollment ELSE 0 END) AS AllSchoolsEnrollment,
COUNT(CASE WHEN institutionswithzipcodesadditional.LevelID IN (4, 5, 6, 7, 8, 14, 15, 16, 20, 13, 12, 10, 11, 9) THEN institutionswithzipcodesadditional.InstitutionID ELSE NULL END) AS AllSchoolsCount
FROM zipcodes
INNER JOIN users_link_territory ON zipcodes.CountyID = users_link_territory.CountyID
INNER JOIN institutionswithzipcodesadditional ON zipcodes.ZIP = institutionswithzipcodesadditional.ZIP
RIGHT OUTER JOIN institutionswithzipcodesadditional AS institutionswithzipcodesadditional_1 ON institutionswithzipcodesadditional.DistrictID = institutionswithzipcodesadditional_1.InstitutionID
WHERE
(institutionswithzipcodesadditional_1.CountyID = 207)
AND (institutionswithzipcodesadditional_1.LevelID IN (1, 2, 3, 6, 7, 8))
GROUP BY institutionswithzipcodesadditional_1.DistrictID, institutionswithzipcodesadditional_1.InstitutionName, institutionswithzipcodesadditional_1.Latitude, institutionswithzipcodesadditional_1.Longitude
查询二:
SELECT
institutionswithzipcodesadditional_1.InstitutionID AS DistrictID,
COUNT(GoldMine.dbo.CONTACT1.ACCOUNTNO) AS GM,
MAX(CASE WHEN GoldMine.dbo.CONTHIST.USERID NOT IN ('DEBRA', 'TRISH', 'RUSSELL', 'GREG') THEN GoldMine.dbo.CONTHIST.OnDate ELSE NULL END) AS LastActivity
FROM institutionswithzipcodesadditional
LEFT OUTER JOIN contacts
LEFT OUTER JOIN GoldMine.dbo.CONTACT1
RIGHT OUTER JOIN GoldMine_Link_Russell
ON GoldMine.dbo.CONTACT1.KEY3 = GoldMine_Link_Russell.GoldMineKeyThree
ON contacts.ContactID = GoldMine_Link_Russell.ContactID
ON institutionswithzipcodesadditional.InstitutionID = contacts.InstitutionID
RIGHT OUTER JOIN institutionswithzipcodesadditional AS institutionswithzipcodesadditional_1
ON institutionswithzipcodesadditional.DistrictID = institutionswithzipcodesadditional_1.InstitutionID
LEFT OUTER JOIN GoldMine.dbo.CONTHIST ON GoldMine.dbo.CONTHIST.ACCOUNTNO = GoldMine.dbo.CONTACT1.ACCOUNTNO
WHERE (institutionswithzipcodesadditional_1.CountyID = 207) AND (institutionswithzipcodesadditional_1.LevelID IN (1, 2, 3, 6, 7, 8))
GROUP BY institutionswithzipcodesadditional_1.InstitutionID
查询三:
SELECT
COUNT(NewsletterContacts.Email) AS EMailableContacts,
institutionswithzipcodesadditional_1.InstitutionID AS DistrictID,
MAX(newsletterregister.Sent) AS LastSent
FROM newsletterregister
RIGHT OUTER JOIN contacts ON newsletterregister.ContactID = contacts.ContactID
RIGHT OUTER JOIN institutionswithzipcodesadditional ON contacts.InstitutionID = institutionswithzipcodesadditional.InstitutionID
LEFT OUTER JOIN EmailableContacts ON institutionswithzipcodesadditional.InstitutionID = EmailableContacts.InstitutionID
RIGHT OUTER JOIN institutionswithzipcodesadditional AS institutionswithzipcodesadditional_1 ON
institutionswithzipcodesadditional.DistrictID = institutionswithzipcodesadditional_1.InstitutionID
WHERE
(institutionswithzipcodesadditional_1.CountyID = 207)
AND (institutionswithzipcodesadditional_1.LevelID IN (1, 2, 3, 6, 7, 8))
GROUP BY institutionswithzipcodesadditional_1.InstitutionID
答案 0 :(得分:4)
是的,你可以使用连接来做到这一点:
SELECT
T1.DistrictID,
T1.NumberofSchools,
T2.NumberofContacts,
T2.LastActivity,
T3.NumberofSubscribers,
T3.LastSent
FROM (SELECT ...) T1
JOIN (SELECT ...) T2 ON T1.DistrictID = T2.DistrictID
JOIN (SELECT ...) T3 ON T1.DistrictID = T3.DistrictID
(SELECT ...)
是三个原始查询的占位符。如果三个查询可以返回不同的区域,也可以考虑使用OUTER JOIN,即如果一个区域出现在一个查询的结果中但在另一个查询中丢失了。
答案 1 :(得分:1)
我偷了Mark的解决方案的一部分,但我想告诉你这个布局的可读性。这样,您就不会将所有三个查询都塞进一个select语句中。这为您提供了一些可以通过临时表或表变量获得的可维护性优势,但是下面的更改更灵活,因为每次添加/删除列时都不必乱用表声明。
With SomeGoodName as
(
SELECT ...
)
,
AnotherDescriptiveName as
(
Select ...
)
,
AThirdNiceName as
(
Select ...
)
SELECT
T1.DistrictID,
T1.NumberofSchools,
T2.NumberofContacts,
T2.LastActivity,
T3.NumberofSubscribers,
T3.LastSent
FROM SomeGoodName T1
JOIN AnotherDescriptiveName T2 ON T1.DistrictID = T2.DistrictID
JOIN AThirdNiceName T3 ON T1.DistrictID = T3.DistrictID
答案 2 :(得分:0)
你会在这里得到一些答案,虽然我同意你“可以”把这一切都整理成一个选择,但我认为你将会有一个更容易维护和更容易运行的过程,如果你使用一些临时表或类似的工作。
例如,创建临时表来存储三个查询中的每个查询的结果,然后将三个临时表连接在一起以获取最终结果并在之后销毁临时表。
通过这种方式,您可以使查询保持正在执行的操作,并且您可以专注于最终聚合。
你可以使用单独的查询来完成这项工作,就像另一张海报所提到的那样,但这很难维护。