2010-12-29 10 views
3

私はすでに自分のSQL知識のピークにある3つのクエリ(Microsoft SQL 2005が重要である)を得ました。そして、それらを1つの行のすべての値を持つ単一のクエリに結合する必要があります。SQL照会と異なる式を組み合わせるにはどうしたらいいですか?

私の実際のクエリは以下の通りですが、私はここに簡易版提供された場合、それが簡単だろうと思った:

クエリワン:

-- 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 

クエリ2:

-- 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 

クエリ3:

-- 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 

クエリ3つのサンプル出力:私はSELECT親でそれらの巨大なUNIONを作ってみた

DistrictID | NumberofSubscribers | LastSent 
345   | 2     | Sep 4, 2010 
567   | 3     | Oct 22, 2010 
211   | 1     | NULL 

ステートメント(詳細はthis weblink以降、各データセットのSELECT NULL AS MissingColumnNameを導入しています)が、実際には醜いです。すべてを1行で返さない。

私はこのような結果を探しています:

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 

は、どのように私はこの作業を行うことができますか? (あなたが興味があれば、私が参加してる本当のクエリは以下の通りです)すべてのあなたの助けを

感謝!

ラッセル・シュッテ

は、私ができる最善のように、これらをクリーンアップ - 申し訳ありません、彼らドン本当に素晴らしい表示されません。 (あまりにもこれらの問題があるかもしれません - 彼らは私の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 

クエリ2:

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 

クエリ3:

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 

答えて

1

私はMarkのソリューションの一部を盗んだが、読みやすいようにこのレイアウトを示したかった。そうすれば、3つのクエリがすべて1つの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 
+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 ...)は、3つの元のクエリのプレースホルダです。 3つのクエリが異なる地区を返すことができる場合、つまりある地区が1つのクエリの結果に存在し、別のクエリの結果に存在しない場合は、OUTER JOINを使用することを検討することもできます。

+0

各結果セットにすべてのDistrictIdがない場合は、LEFT結合またはFULL OUTER結合が必要な場合があります。 – HLGEM

+1

同じ要約では、クエリのテーブルの名前を変更することを検討しましたので、代わりにzipcodeswithditionalの代わりにaddlZipsのようなものを入力できますか?エイリアス情報はこちら:http://www.w3schools.com/Sql/sql_alias.asp – rownage

+0

@HLGEM:ありがとう、更新されました。 –

0

あなたはここでいくつかの回答を得ようとしていますが、私はあなたがこのすべてを1つの選択肢にすることに同意しますが、一時的なテーブルなどで少し作業します。

たとえば、3つの各クエリの結果を格納する一時テーブルを作成し、次に3つのtempテーブルを結合して最終結果を得てから、後で一時テーブルを破棄します。

このようにして、自分が行っていることをやり遂げることができ、最終的な集約に集中することができます。

これは、別のポスターが述べているように個々のクエリを使用して行うことができますが、維持するのは非常に難しくなります。

+0

ありがとうMitchel。私は一時的なテーブルに慣れていないので、あなたは私をもっと知りたいと思っています - マルチユーザアプリケーションの参考文献はありますか? (私はユーザーがお互いのテンポラリテーブルの束にアクセスしているので、悪い結果を出すことは嫌です)プログラミング言語を使って3つの異なるクエリから値を参照して並べ替えることができました。私はデータベースができると思った。 –

関連する問題