如何在子查询中使用HAVING作为Select语句的一部分

时间:2015-02-25 17:04:56

标签: mysql subquery having

我正在进行一项调查,以便回报今年有多少活动家不止一次被团队自愿提供;我让它作为一个独立的查询工作:

   SELECT Activists.team, COUNT(id) AS Activists
    FROM
    (
        SELECT e.id, v.team, 
        COUNT(CASE WHEN (e.status="Completed" AND right(e.date,2)="15") THEN e.id END) AS count
        FROM actiontable e
        LEFT JOIN persontable v ON v.id = e.id
        GROUP BY e.id, v.team
        HAVING (count > 1)
    ) AS Activists
    GROUP BY Activists.team;

但我无法弄清楚如何让它在较长的SELECT语句中运行。我遇到的问题是,我还有许多其他(更简单)的查询部分,以便在SELECT语句中按团队返回内容,如:

COUNT(DISTINCT CASE WHEN v.WillCanvass = "X" THEN v.id END)

显然,我不能为活动家提供HAVING (count > 1)部分查询,因为这会影响我SELECT语句的所有其他部分 - 所以我需要上面的子查询只影响我工作的唯一部分。

我创建了一个带有示例架构的SQL Fiddle来帮助解决上述有效的问题 - 但理想的情况是获得与此类似的输出,其中Activists子查询没有&#39} ; t影响WillCanvass列(即使我编写了下面的数字):

Team    Activists   WillCanvass
Team A  2           2
Team B  8           5
Team C  7           3

希望有道理 - 谢谢!


修改

我对我想要的最好的镜头 - 虽然查询给我错误 - 看起来像这样:

SELECT a.team as team,
    COUNT(v.*) as activists,
    SUM(CASE WHEN v.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass
FROM
persontable v
left join
(
    SELECT e.id, 
        v.team,
        v.WillCanvass,
        COUNT(*) as count
    FROM actiontable e
    LEFT JOIN persontable v ON v.id = e.id
    WHERE e.status="Completed" AND right(e.date,2)="15"
    GROUP BY e.id
    HAVING (count > 1)) as a 
        GROUP BY team;

有一个更新的SQL小提琴here

3 个答案:

答案 0 :(得分:2)

不确定您想要实现的目标。我首先获得具有正确标准的活动家列表,然后是GROUP BY团队。

SELECT a.team as team,
    COUNT(*) as activists,
    SUM(CASE WHEN a.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass
FROM (
    SELECT e.id, 
        v.team,
        v.WillCanvass,
        COUNT(*) as count
    FROM actiontable e
    LEFT JOIN persontable v ON v.id = e.id
    WHERE e.status="Completed" AND right(e.date,2)="15"
    GROUP BY e.id
    HAVING (count > 1)) as a 
GROUP BY team

答案 1 :(得分:0)

尝试这种方式:

http://sqlfiddle.com/#!2/e186da/5

SELECT  v.team as team, 
        SUM(CASE WHEN (e.status="Completed" AND YEAR(e.date)="2015") THEN 1 ELSE 0 END) AS count
        FROM actiontable e
        LEFT JOIN persontable v ON v.id = e.id
        GROUP BY v.team
        HAVING (count > 1);


SELECT  v.team as team, 
        SUM(CASE WHEN (e.status="Completed" AND YEAR(e.date)="2015") THEN 1 ELSE 0 END) AS count,
        SUM(CASE WHEN (v.WillCanvass='X') THEN 1 ELSE 0 END) AS WillCanvass
        FROM actiontable e
        LEFT JOIN persontable v ON v.id = e.id
        GROUP BY v.team

答案 2 :(得分:0)

我明白了 - 谢谢你帮助我到达那里,但它与上面的任何东西都有很大的不同。我必须完全取消HAVING子句,以使SELECT语句的第一部分(WillCanvass)完全独立于actiontable部分:

SELECT a.team as team,
    COUNT(case when a.X > 1 then a.id else null end) as activists,
    SUM(CASE WHEN a.WillCanvass = "X" THEN 1 ELSE 0 END) as WillCanvass
FROM (
    SELECT v.id, 
        v.team,
        v.WillCanvass,
        COUNT(case when e.status="Completed" AND right(e.date,2)="15" then e.id else null end) as X
    FROM actiontable e
    RIGHT JOIN persontable v ON v.id = e.id
    GROUP BY v.id, v.team, v.WillCanvass
 ) as a 
GROUP BY team;

这是一个新的SQL Fiddle,看看它是如何运作的。