SELECT db.people.first_name,
db.people.last_name,
db.people.email
FROM db.convert, db.people
HAVING COUNT(db.convert.year) > 1
WHERE db.convert.email = db.people.email
AND (SUBSTRING(db.convert.gross, 1, 2) != '$-')
GROUP BY db.people.email
这个查询在没有HAVING语句的情况下工作正常,但我需要它只选择表中包含不同年份的多个记录的电子邮件。所以2011年,2012年,2013年
此外,我希望它只显示一次电子邮件和姓氏,不同吗?
当我添加having语句时,查询无法运行
答案 0 :(得分:2)
以下是编写此查询的更好方法:
SELECT p.first_name, p.last_name, p.email
FROM db.convert c join
db.people p
on c.email = p.email
WHERE c.gross not like '$-%'
GROUP BY p.email
HAVING COUNT(c.year) > 1;
除了使用having
修复语法问题外,我还要:
c
和p
)以使查询更具可读性。where
子句中使用正确的连接语法而不是隐式连接。like
而不是substring()
,因此比较可以利用索引。另外,COUNT(c.year)
可能不会做你想要的。它可能与COUNT(c.gross)
,COUNT(c.email)
和COUNT(*), because it counts the number of non-NULL values in
年`相同。我不确定你想要什么,但如果你想要至少有两年记录的电子邮件,那么表达式应该是:
HAVING COUNT(DISTINCT c.year) > 1
答案 1 :(得分:1)
HAVING基于GROUP BY条件。所以它需要在GROUP BY之后。
GROUP BY db.people.email HAVING COUNT(db.convert.year) > 1
正如Ollie Jones和Gordon Linoff建议的那样,如果每个人每年有多个记录,那么你会想要在COUNT上使用DISTINCT,这样你每年都不会多次计算:
GROUP BY db.people.email HAVING COUNT(DISTINCT db.convert.year) > 1
答案 2 :(得分:0)
看来你有两个要求。 (我假设一封电子邮件唯一地标识了一个人。)
一,列出人员名单'姓名和电子邮件。
二,显示在convert
表中出现多个不同年份的人。
此查询可以满足第二个要求。它通过电子邮件计算不同的转换年份,并抛出只有一个转换年份的转换年份。正如有人在评论中提到的那样,HAVING
应该在GROUP BY
之后。
SELECT COUNT(DISTINCT year) AS years, email
FROM db.convert
WHERE SUBSTRING(gross, 1, 2) !- '$-'
GROUP BY email
HAVING COUNT(DISTINCT year) > 1
然后我们可以使用它作为子查询(虚拟表)来获得人们的关注。名称,如下:
SELECT p.first_name,
p.last_name,
p.email
FROM db.people AS p
JOIN (
SELECT COUNT(DISTINCT year), email
FROM db.convert
WHERE SUBSTRING(gross, 1, 2) !- '$-'
GROUP BY email
HAVING COUNT(DISTINCT year) > 1
) AS years ON p.email = years.email
ORDER BY p.last_name, p.first_name, p.email
这会精确地使用结构化查询语言的结构化部分来指定表格所需的内容。
以这种方式构建查询可让您逐步调试事物。在表连接中使用COUNT()
或其他聚合函数时必须要小心,因为由于组合方式的加入,你可能会得到比你讨价还价更多的行。