Mysql 使用“仅为特定字段选择多条记录”

Mysql 使用“仅为特定字段选择多条记录”,mysql,Mysql,这个查询在没有have语句的情况下运行良好,但我需要它只选择表中具有不同年份的多条记录的电子邮件。那么2011年、2012年、2013年呢 我还想让它显示,电子邮件和姓氏只有一次,不同 添加having语句时,查询不会运行。having基于GROUPBY条件。所以它需要在小组之后 SELECT db.people.first_name, db.people.last_name, db.people.email FROM db.convert, db.people HAVING C

这个查询在没有have语句的情况下运行良好,但我需要它只选择表中具有不同年份的多条记录的电子邮件。那么2011年、2012年、2013年呢

我还想让它显示,电子邮件和姓氏只有一次,不同


添加having语句时,查询不会运行。

having基于GROUPBY条件。所以它需要在小组之后

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 
正如奥利·琼斯(Ollie Jones)和戈登·林诺夫(Gordon Linoff)所建议的那样,如果每个人每年都有一个以上的记录,那么你就需要在计数时使用一个独特的数字,这样你就不会每年数数一次以上:

GROUP BY db.people.email HAVING COUNT(db.convert.year) > 1

以下是编写此查询的更好方法:

GROUP BY db.people.email HAVING COUNT(DISTINCT db.convert.year) > 1
除了修复
have
的语法问题外,我还:

  • 引入表别名(
    c
    p
    )使查询更具可读性
  • where
    子句中使用正确的联接语法,而不是隐式联接
  • 使用类似于的
    而不是
    子字符串()
    ,这样比较就可以利用索引
而且,
COUNT(c.year)
可能并不能满足您的需求。它可能与
COUNT(c.gross)
COUNT(c.email)
、和
COUNT(*)相同,因为它计算的是
year`中非空值的数量。我不确定你想要什么,但如果你想要有至少两年记录的电子邮件,那么表达应该是:

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;

你似乎有两个要求。(我假设一封电子邮件唯一地标识了一个人。)

第一,列出一张名单,上面有人的名字和电子邮件

第二,在您的
convert
表中显示在一个以上不同年份出现的人员

此查询可以满足第二个要求。它通过电子邮件统计不同的转换年数,并将只有一个转换年的转换年数丢弃。正如有人在评论中提到的,
拥有
应该排在
分组依据
之后

HAVING COUNT(DISTINCT c.year) > 1
然后,我们可以将其用作子查询(虚拟表)来获取人名,如下所示:

SELECT COUNT(DISTINCT year) AS years, email
  FROM db.convert
 WHERE SUBSTRING(gross, 1, 2) !- '$-'
 GROUP BY email
HAVING COUNT(DISTINCT year) > 1
这使用结构化查询语言的结构化部分精确地指定您需要从表中获得什么


以这种方式构建查询可以让您逐步调试。在表联接中使用
COUNT()
或其他聚合函数时必须小心,因为由于组合方式联接的工作方式,您可能会得到比预期多得多的行。

是否应该跟踪组或无所谓?太棒了,查询现在可以工作了,没有更多错误。很高兴它可以工作,我必须尽快恢复精神。你不需要像我建议的那样使用count(*),只要把HAVING放在小组后面就行了。我添加了一个答案。添加得不错。别名和“不喜欢”我同意,但是隐式连接有什么特别的错误吗?或者你的目的只是为了让用户知道连接在哪里?Devon。让我们说,大多数使用SQL的人都同意隐式联接是非常糟糕的样式。每个数据库都支持它们,它们是ANSI标准的正式组成部分,但它们很难维护,表达能力较差(不支持外部联接),更难阅读,更容易出错。这正是我所需要的,您也预先考虑过我对DISTINCT的需要。因为我想选择多个不同的年份。使用JOIN会使查询在不同的接口上更“可靠”吗?我使用的是一个专有的命令行工具,隐式连接给出了错误的结果。但它们在腻子上都能正常工作(结果相同)。再次感谢。@alex_b。隐式连接和等效的内部连接应该给出相同的结果。如果您观察到不同的行为,您可能想在这里或dba.stackexchange.com上问一个问题。OP可能希望
COUNT(DISTINCT db.convert.year)>1
,以我的阅读方式满足要求。@OllieJones是的,很好,此查询假设db.convert.year是唯一的列。
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