使用HAVING仅为特定字段选择多个记录

时间:2014-04-19 20:15:30

标签: mysql

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语句时,查询无法运行

3 个答案:

答案 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修复语法问题外,我还要:

  • 引入表别名(cp)以使查询更具可读性。
  • 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()或其他聚合函数时必须要小心,因为由于组合方式的加入,你可能会得到比你讨价还价更多的行。