COUNT(DISTINCT Column1)仅适用于多列的一列

时间:2013-05-10 14:03:35

标签: mysql count distinct

不可否认,我已经在这里看过几次这个问题了 - 但所有答案似乎都是通过使用GROUP BYWHERE来解决他们的问题,所以我很好奇如何获得如果你的查询太大而无法正常工作,那么就可以了。

例如,我正在写一些使用两个左连接到我的主表的东西,将重叠带到结果中。因为我还是比较新的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 个答案:

答案 0 :(得分: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