【问题标题】:MySQL : Having doesn't workMySQL:拥有不起作用
【发布时间】:2018-07-06 10:15:03
【问题描述】:

我正在使用 MySQL。这是我的架构:

表 b

Column Name |   Type   | Primary key
id          |   int    |    Yes
seq         |   int    |    Yes
amt         |   int

虚拟数据

id   |  seq  | amt
1    |   1   | 4000
1    |   2   | 3000
1    |   3   | 2000
1    |   4   | 5000   
2    |   1   | 4000
2    |   2   | 3000
3    |   1   | 2000
3    |   2   | 5000

我想选择具有等效 id 和 seq 最大值的记录。 这是我的 SQL

SELECT b.id, b.seq, b.amt
FROM b
WHERE b.id = 1
AND b.seq = 
(SELECT max(b.seq) FROM b WHERE b.id = 1)

但我想知道是否有更优雅的方式来实现我想要的。 例如,

SELECT b.id, b.seq, b.amt
FROM b
WHERE b.id = 1
HAVING b.seq = max(b.seq)

但它没有按预期工作。它返回 0 行。

【问题讨论】:

  • @nammae...供您参考,HAVING 与结果组一起使用...意味着您可以将其与 GROUP BY 子句一起使用...例如
  • SQL,优雅没办法...

标签: mysql having


【解决方案1】:

对数据排序,只取第一条记录

SELECT b.id, b.seq, b.amt
FROM b
WHERE b.id = 1
ORDER BY seq desc
limit 1

【讨论】:

  • 感谢您的解决方案。但是你能告诉我为什么我的第二种方法不起作用吗?
  • 因为having 设计为与group by 一起使用。在 having 子句中,只应使用聚合函数,如 max() 或您根本不做的分组列。
【解决方案2】:

举个简单的例子,这个怎么样:

SELECT b.id, b.seq, b.amt
FROM b
WHERE b.id = 1 ORDER BY b.seq DESC limit 1;

【讨论】:

    【解决方案3】:

    HAVING 子句将与您的查询中缺少的 GROUP BY 子句一起使用。要将GROUP BY 子句添加到您的查询中,我们必须包含查询中没有聚合函数的所有字段,因此除seq 之外的所有字段:

    SELECT b.id, b.seq, b.amt
    FROM b
    WHERE b.id = 1
    GROUP BY b.id, b.amt
    HAVING b.seq = MAX(b.seq)
    

    现在这显然不会给您正确的结果,因为您只想按id 而不是amt 分组。另一个问题是你不能在SELECTHAVING子句中使用不在GROUP BY子句中的字段,所以你不能在这两个地方使用seq,上面的查询会给你一个错误。

    如果您的目标是获取 id = 1 的记录,那么您的第一个查询是可以的,或者更好地使用 juergen 的答案中的查询。但是,如果您的真正目标是为每个组选择一条记录,那么您可以这样做:

    SELECT b.id, b.seq, b.amt
    FROM b
    INNER JOIN (SELECT id, MAX(seq)
                FROM b
                GROUP BY id) bb ON bb.id = b.id AND bb.seq = b.seq
    

    结果将是:

    id   |  seq  | amt
    1    |   4   | 5000   
    2    |   2   | 3000
    3    |   2   | 5000
    

    【讨论】:

      【解决方案4】:

      SQL HAVING 子句

      • HAVING 过滤适用于汇总 GROUP BY 结果的记录。
      • HAVING 适用于汇总组记录,而 WHERE 适用于单个记录。
      • 只会返回满足 HAVING 条件的组。
      • HAVING 要求存在 GROUP BY 子句。
      • WHERE 和 HAVING 可以在同一个查询中。

      【讨论】:

      • 这里有一个测验:结果记录中amt的值是多少?很好的解释,但非常糟糕的查询。在开始投反对票之前,请考虑将其删除(或修复)。
      • 它相当于 max(seq),这里是 5000,用于 id=1 的虚拟数据。仅供参考,我已经发布了查询来解释 have 子句的使用并保持简单,因为@nammae 有兴趣知道为什么没有为他工作。
      • 错误答案。你没有通过测验:)。 amt 的值未定义。意思是,我们不知道价值是什么。阅读here for a good explanation of the problem。与其他数据库不同,MySQL 决定不遵循规范,因此不会引发错误,但结果未定义。顺便说一句,如果需要,您可以将查询保留为示例,只需删除 amt 列。为什么你认为虚拟数据没有意义?看起来不错。
      • SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列。然而,MySQL 支持这种行为的扩展,并允许 HAVING 引用 SELECT 列表中的列和外部子查询中的列。 dev.mysql.com/doc/refman/5.7/en/select.html 在这种情况下无济于事,但很有用。
      • 虚拟数据有重复的 Id 条目。虽然表结构将其定义为主键
      猜你喜欢
      • 1970-01-01
      • 2014-07-20
      • 2023-04-11
      • 2017-02-27
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多