如何在子查询中使用 HAVING 作为 Select 语句的一部分
How to Use HAVING in a Subquery as Part of a Select Statement
我正在查询 return 今年有多少活动家按团队不止一次志愿服务;我让它作为一个独立的查询工作:
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
语句中,我还有许多其他(更简单的)查询部分 return 团队的事情,例如:
COUNT(DISTINCT CASE WHEN v.WillCanvass = "X" THEN v.id END)
所以显然我不能为活动家查询 HAVING (count > 1)
部分,因为那样它会影响我的 SELECT
语句的所有其他部分——所以我需要上面的子查询只影响我正在处理的唯一部分。
我用示例模式创建了一个 SQL Fiddle 来帮助上面的查询工作——但理想的是得到一个看起来与此类似的输出,其中 Activists
子查询没有'影响 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 Fiddle here。
试试这个方法:
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
不确定您要实现的目标。我首先获得具有正确标准的活动家名单,然后是 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
我明白了 - 感谢您帮助我到达那里,但它与上面的任何内容都非常不同。我必须完全删除 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,看看它是如何工作的。
我正在查询 return 今年有多少活动家按团队不止一次志愿服务;我让它作为一个独立的查询工作:
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
语句中,我还有许多其他(更简单的)查询部分 return 团队的事情,例如:
COUNT(DISTINCT CASE WHEN v.WillCanvass = "X" THEN v.id END)
所以显然我不能为活动家查询 HAVING (count > 1)
部分,因为那样它会影响我的 SELECT
语句的所有其他部分——所以我需要上面的子查询只影响我正在处理的唯一部分。
我用示例模式创建了一个 SQL Fiddle 来帮助上面的查询工作——但理想的是得到一个看起来与此类似的输出,其中 Activists
子查询没有'影响 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 Fiddle here。
试试这个方法:
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
不确定您要实现的目标。我首先获得具有正确标准的活动家名单,然后是 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
我明白了 - 感谢您帮助我到达那里,但它与上面的任何内容都非常不同。我必须完全删除 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,看看它是如何工作的。