2013-05-10 26 views
-2

無可否認,我在這裏看過這個問題幾次 - 但所有答案似乎都通過使用GROUP BYWHERE來解決他們的問題,所以我是好奇如何解決這個問題,如果你的查詢變得太大而無法工作。COUNT(DISTINCT Column1)僅適用於多列中的一列

例如,我正在寫一些使用兩個左連接到我的主表,使重疊進入結果。由於我對SQL還比較陌生,因此我不確定它在做什麼 - 但是我知道當我運行這些計數時我會得到一千多人。我在想象這種情況,因爲在我加入的兩個表中,每個人都有重複的ID(有目的地)。

我想爲此項目獲得的所有結果都使用COUNT()SUM()掛起。有沒有一種方法可以使用DISTINCT一次只生成一列,只將我的ID作爲一個整體處理?根據我迄今所做的工作,我注意到,無論您何時設置DISTINCT,它的工作原理都超出了您試圖將其歸入的那一列。有什麼建議麼?這將非常感激!

這裏是我的代碼的例子,到目前爲止,包括重複的ID:

SELECT 
    targeted.person AS "Person", 
    targeted.work AS "Occu", 
    (COUNT(targeted.id)) AS "Targeted", 
    (COALESCE(SUM(targeted.signed="Yes"),0)) AS "Signed", 
    (COALESCE(SUM(targeted.signed="Yes"),0))/COUNT(targeted.id)*100 AS "Signed %", 
    (COALESCE(COUNT(question.questionid="96766"),0)) AS "Donated", 
    (COALESCE(COUNT(question.questionid="96766"),0))/(COALESCE(SUM(targeted.signed="Yes"),0))*100 AS "Donated %", 
    (COALESCE(SUM(question.surveyresponsename),0)) AS "Donation $", 
    ROUND((COALESCE(SUM(question.surveyresponsename),0))/(COALESCE(COUNT(question.questionid="96766"),0)),2) AS "Avg Donation", 
    (CASE WHEN (left(targeted.datesigned,1)="5" AND right(question.datecontacted,2)="13") THEN (COALESCE(SUM(targeted.signed="Yes"),0)) ELSE 0 END) AS "Signed This Month", 
    (CASE WHEN (left(question.datecontacted,1)="5" AND right(question.datecontacted,2)="13") THEN (COALESCE(COUNT(question.questionid="96766"),0)) ELSE 0 END) AS "Donated This Month", 
    (CASE WHEN question.ContactType="House Visit" THEN COUNT(question.id) ELSE 0 END) AS "At Home", 
    (CASE WHEN question.ContactType="Worksite" THEN COUNT(question.id) ELSE 0 END) AS "At Work", 
    (CASE WHEN (left(events.day,1)="5" AND right(events.day,2)="13") THEN COUNT(events.id) ELSE 0 END) AS "Events This Month" 
     FROM targeted 
     LEFT JOIN question ON targeted.id=question.id 
     LEFT JOIN events ON targeted.id=events.id 
     GROUP BY targeted.person, targeted.work; 

這裏是表結構的基礎:

目標:

Field  Type   Null Key  Default 
ID   bigint(11)  YES  Primary NO 
Work  varchar(255) YES    NULL 
Person  varchar(255) YES    NULL 
Signed  varchar(255) YES    NULL 
DateSigned varchar(255) YES    NULL 

問題:

Field    Type   Null Key  Default 
ID     bigint(11)  YES  Primary NO 
QuestionID   int(11)   YES    NULL 
SurveyResponseId int(11)   YES    NULL 
SurveyResponseName varchar(255) YES    NULL 
DateContacted  varchar(255) YES    NULL 
ContactType   varchar(255) YES    NULL 

個活動:

Field  Type   Null Key  Default 
ID   bigint(11)  NO  Primary NO 
Day   varchar(255) YES    NULL 
EventType varchar(255) YES    NULL 

,其結果將是爲了看起來像:

Person Occu Targeted Signed Signed % ... 
1  Job 1 1413  765  54.14 ... 
2  Job 2 111   80  72.072 ... 
2  Job 3 931   715  76.7991 ... 
3  Job 4 2720  1435 52.7573 ... 
4  Job 5 401   218  54.364 ... 

感謝您的幫助!

+1

「左連接...不完全確定是什麼在做」< - 實際上是想停止閱讀那裏。在使用它們之前學習左連接怎麼樣?它的作品完全像你的標題說的。爲什麼不試一試,或者谷歌呢?當我們不知道用於生成數據的數據時,所期望的結果也不是很有幫助。 – fancyPants 2013-05-10 14:19:34

+0

你可以添加表結構的問題?另外,你確定你應該加入'id'字段中的表格嗎? – 2013-05-10 14:20:54

+0

@tombom不完全確定你在說什麼?我對使用左連接感到相當有信心。我對它們進行了研究,它們的工作原理就像填寫第一組數據和第二組數據的交點的維恩圖一樣。如果我沒有Google或測試它,可能不會寫這個。提供幫助通常比假設我什麼都不知道更好。謝謝! – Ryan 2013-05-10 14:36:36

回答

0

解決此問題的正確方法是在子查詢中進行聚合。要將問題和事件彙總到正確的級別,您需要加入目標表格。然後,你不需要在最外層的聚合:

select . . . 
from (select t.name, t.work, 
      count(t.id) as Targeted, 
      . . . 
     from targets t 
     group by t.name, t.work 
    ) t left join 
    (select t.name, t.work, 
      sum(case when question_id = 96766 then 1 else 0 end) as Donated, 
      . . . 
     from question q join 
      targeted t 
      on t.id = t.id 
     group by t.name, t.work 
    ) q 
    on t.name = q.name and t.work = q.work left join 
    (select t.name, t.work, 
      sum(CASE WHEN (left(events.day,1)="5" AND right(events.day,2)="13") THEN 1 ELSE 0 END 
       ) AS "Events This Month" 
    from events e join 
      targeted t 
      on e.id = t.id 
    ) e 
    on e.name = t.name and e.work = t.work 
+0

感謝您的幫助! – Ryan 2013-05-10 15:22:51