2014-07-08 27 views
1

我寫了下面的查詢,它顯示了與兩個特定的ables關聯的ApplicationID。我需要結果來返回每個Applications.AppID出現在具有應用程序名稱的行旁邊的那些表中的次數。我使用的是獨特的,因爲在我的結果中,我只希望名稱出現一次,但在其旁邊有一個數字,表示它已被使用了多少次。下面的例子。我以前寫過計數條件,但僅限於單個表格。如何計算並顯示一行在多個連接表中出現的次數?

SELECT 0 AppId , 
     'Select an Application' ApplicationName 
union all 
    select .1  , 
     '--All--' 
union all 
    SELECT DISTINCT 
     Applications.AppId , 
     Applications.ApplicationName 
    FROM ImpactedApplications , 
     SupportingApplications 
    JOIN applications    ON SupportingApplications.Appid = applications.appid 
    JOIN ImpactedApplications Apps on SupportingApplications.AppId = Applications.AppId 

返回是這樣的:

0.0 Select an Application 
0.1 --All-- 
12.0 APP A 
59.0 APP B 
60.0 APP C 
71.0 APP D 
74.0 APP E 
121.0 APP F 
124.0 APP G 
130.0 APP H 

我想這回是這樣的:

0.0 Select an Application 
0.1 --All-- 
12.0 APP A 1 
59.0 APP B 2 
60.0 APP C 1 
71.0 APP D 4 
74.0 APP E 3 
121.0 APP F 1 
124.0 APP G 2 
130.0 APP H 2 

任何幫助表示讚賞謝謝。

從幫助查詢

12 APP A 17161 
59 APP B 51483 
60 APP C 85805 
71 APP D 17161 

回答

0

首先,你意識到訂單是未指定除非您使用order by命令結果集?這意味着不能保證您的union all中的前兩個選項會排在第一位。

因此,讓我們將這兩個問題去掉,因爲它們與實際問題無關。讓我們考慮的核心select

從ImpactedApplications選擇不同 Applications.AppId, Applications.ApplicationName , SupportingApplications JOIN ON SupportingApplications.Appid = applications.appid 應用JOIN ImpactedApplications應用上SupportingApplications.AppId =應用程序。 AppId

並解剖它。

問題#1。
select distinct通常是代碼異味表示您沒有正確的連接標準,或者您沒有正確理解所涉及關係的基數。

問題#2。
確實如此。您正在將舊學校,ISO/ANSI之前的加入與ISO/ANSI加入混合。由於在FROM子句中前兩個表的連接預ISO/ANSI風格,和你有什麼標準來加入他們沒有where條款,上述select語句完全相同

選擇不同 a.AppId, 一個。從ImpactedApplications應用程序名稱 保險業監督 交叉連接SupportingApplications SA 上sa.Appid = a.appid 加入ImpactedApplications應用程序加入應用程序上sa.AppId = a.AppId

我敢肯定你不打算生成2張桌子的笛卡爾產品。您還沒有描述表模式,但我懷疑,從您的問題聲明

我需要的結果的時候每個Applications.AppID 出現這些表中的數字返回與應用程序名稱的行旁邊。

是要沿着這些路線的更多的東西:

select AppId   = a.AppId   , 
     AppName   = a.ApplicationName , 
     ImpactedCount = coalesce(ia.Cnt , 0) , 
     SupportingCount = coalesce(sa.Cnt , 0) , 
     Total   = coalesce(ia.Cnt , 0) 
         + coalesce(sa.Cnt , 0) 
from  Applications   a 
left join (select AppId = t.AppId , 
        Cnt = count(*) 
      from ImpactedApplications t 
      group by t.AppId 
     ) ia on ia.AppId = a.AppId 
left join (select AppId = t.AppId , 
        Cnt = count(*) 
      from SupportingApplications t 
      group by t.AppId 
     ) sa on sa.AppId = a.AppId 

如果你想限制的結果,只是那些具有非零值的行,你可以在left join條款更改爲join,但這意味着你只會得到那些對於兩者都有非零值的行。相反,添加一個WHERE子句限制結果集:

where sa.Cnt > 0 
    OR ia.Cnt > 0 

除了過濾掉其中兩個計數爲零的任何行,它還會刪除其中兩行有null count行,表明發生了不匹配left join

+0

這工程太棒了!我可以從中刪除受影響和支持的計數,並僅使用總數!另外,有沒有一種方法可以將其限制爲僅包含總數的項目?現在它的許多值返回0。 – OnceorTwice

+0

@OnceorTwice,看我編輯的答案。 –

+0

完美!這正是我所需要的!謝謝! – OnceorTwice

1

DISTINCT增加的結果是邏輯上等同於一個GROUP BY:

SELECT Applications.AppId, Applications.ApplicationName 
    ,COUNT(*) 
FROM SupportingApplications 
INNER JOIN applications ON SupportingApplications.Appid = applications.appid 
INNER JOIN ImpactedApplications as Apps on SupportingApplications.AppId = Applications.AppId 
GROUP BY Applications.AppId, Applications.ApplicationName 
+0

謝謝你的想法。當我嘗試這個時,我收到了一個非常大的數字。在成千上萬的時候,當我確定它應該只有兩三個。我將結果包含在我原來的帖子中。任何想法是什麼原因? – OnceorTwice

+0

沒有條件加入ImpactedApplications的第二個副本,從而導致交叉連接。你可能根本不需要它,所以只需將其刪除即可。編輯我的答案。 – dnoeth

+0

這是有效的,但是它將數值減少到了更低的數值,但仍然在數百個數值中。如果我刪除ImpactedApplications上的Inner Join,它將起作用。但我確實需要這兩個表格的總數。 – OnceorTwice

0
SELECT 0 AppId, 'Select an Application' ApplicationName union all 
           select .1,'--All--' union all 
SELECT DISTINCT app.AppId, app.ApplicationName,count(app.AppId) 
FROM SupportingApplications sa 
INNER JOIN applications app ON sa.Appid = applications.appid 
--INNER JOIN ImpactedApplications as Apps on sa.AppId = app.AppId 
group by app.AppId, app.ApplicationName 

它看起來並不像你這樣做有ImpactedApplications表什麼,所以IDK的也許刪除該行

+0

嘿。感謝您的反饋。我正在使用受影響的應用程序。我需要它查看AppIds的支持和影響。 – OnceorTwice

相關問題