【问题标题】:How to query MIN value of MAX subquery with two distinct columns?如何使用两个不同的列查询 MAX 子查询的 MIN 值?
【发布时间】:2021-06-14 19:27:04
【问题描述】:

我有一张这样的桌子:

+---------------+--------------+------+-----+----------+
| Field         | Type         | Null | Key | Default  |
+---------------+--------------+------+-----+----------+
| id            | smallint(6)  | NO   | PRI | NULL     |
| Book          | tinyint(4)   | NO   |     | NULL     |
| Chapter       | smallint(6)  | NO   |     | NULL     |
| Paragraph     | smallint(6)  | NO   |     | NULL     |
| Text          | text         | YES  |     | NULL     |
| RevisionNum   | mediumint(9) | NO   | PRI | NULL     |
+---------------+--------------+------+-----+----------+

mysql> select id,Book,Chapter,Paragraph,RevisionNum FROM MyTable ORDER BY id LIMIT 11;

+-----+------+---------+-----------+-------------+
| id  | Book | Chapter | Paragraph | RevisionNum |
+-----+------+---------+-----------+-------------+
|   1 |    1 |       1 |         1 |           0 |
|   1 |    1 |       1 |         1 |           1 |
|   1 |    1 |       1 |         1 |           2 |
|   2 |    1 |       2 |         2 |           0 |
|   2 |    1 |       2 |         2 |           1 |
|   2 |    1 |       2 |         2 |           2 |
|   2 |    1 |       2 |         2 |           3 |
|   3 |    1 |       2 |         3 |           0 |
|   4 |    1 |       2 |         4 |           0 |
|   4 |    1 |       2 |         4 |           1 |
|   5 |    1 |       3 |         5 |           0 |
+-----+------+---------+-----------+-------------+

要查找没有未修改段落的书或章节, 我想查询最大值的最小值 该章节或书籍的所有不同ID,或者在 某些时尚确定没有 id 未被编辑(带有 MAX(RevisionNum) 为零)。

迄今为止,我的大部分尝试都以这样的错误告终:

SELECT DISTINCT Book,RecordNum FROM MyTable
    -> WHERE 0 < ALL (SELECT DISTINCT RecordNum,MAX(RevisionNum) 
                      FROM MyTable 
                      WHERE MAX(RevisionNum) > 0);
                      
ERROR 1111 (HY000): Invalid use of group function

...而且我根本没有使用“GROUP BY”功能!

下面的查询会产生结果,但很简单 给出所有 id,实际上并不显示唯一的 根据要求设置账簿记录。怎么会这样?

SELECT DISTINCT Book,id,MAX(RevisionNum) FROM MyTable GROUP BY id LIMIT 5;

+------+----+------------------+
| Book | id | MAX(RevisionNum) |
+------+----+------------------+
|    1 |  1 |               30 |
|    1 |  2 |               16 |
|    1 |  3 |               15 |
|    1 |  4 |               10 |
|    1 |  5 |                9 |
+------+----+------------------+

正确的查询应该是给出更像这样的结果:

+------+-----+-----------------------+
| Book |  id | MIN(MAX(RevisionNum)) |
+------+-----+-----------------------+
|    1 |   5 |                     3 |
|    2 |  17 |                     1 |
|    3 |  33 |                     2 |
|    4 | 147 |                     0 |
|    5 | 225 |                     2 |
+------+-----+-----------------------+

【问题讨论】:

  • 17、33等数字从何而来?
  • SELECT RecordNum,MAX(RevisionNum) 需要GROUP BY
  • GROUP BY 不是函数; MAX(对一组行进行操作)是。
  • @Gordon 这些是相关段落的实际 ID。显示的表格已针对该问题进行了截断,但有数万个 ID,每个 ID 都有一个或多个修订版。
  • MAX,正如我所指出的,是一个组函数;这就是错误所指的内容。

标签: mysql sql mariadb


【解决方案1】:

您是否在寻找两个级别的聚合?

select id, book, min(max_revisionnum)
from (select id, book, chapter, paragraph, max(revisionnum) as max_revisionnum
      from mytable
      group by id, book, chapter, paragraph
     ) t
group by id, book;

编辑:

根据您的评论,您可以使用:

select *
from (select id, book, chapter, paragraph, max(revisionnum) as max_revisionnum,
             row_number() over (partition by book order by max(revisionnum) desc) as seqnum
      from mytable
      group by id, book, chapter, paragraph
     ) t
where seqnum = 1;

Here 是一个 dbfiddle。

在旧版本的 MariaDB 中,您可以使用关联子查询:

select t.*
from mytable t
where (id, book, chapter, paragraph, revisionnum) = (select t2.id, t2.book, t2.chapter, t2.paragraph, t2.revisionnum
                                                     from mytable t2
                                                     where t2.book = t.book
                                                     order by t2.revisionnum desc
                                                     limit 1
                                                    );

对于此查询,请尝试在 (book, revisionnum desc) 上添加索引。

【讨论】:

  • 我正在为每本书寻找一个唯一的结果,显示具有最低 RevisionNum 的 id。如果一个段落从未被编辑过,它仍然只有它的原始 id,RevsionNum 为 0。我想要一个列表,列出所有仍有未编辑段落的书。
  • 我认为这个答案给出了相同的结果:SELECT DISTINCT id,Book,MAX(RevisionNum) FROM MyTable GROUP BY id;这相当于列出所有可能的 id(在我的情况下是数千个)。
  • @Polyhat 。 . .你的评论比你的问题清楚得多。我在答案中添加了一个编辑以显示您想要的内容。
  • 您编辑的版本在“分区”点上犹豫不决。 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(partition by Book ... 有什么明显的地方可以纠正吗?我以前从未使用过partition
  • @Polyhat 。 . . .您必须使用非常旧的 MariaDB 版本。该数据库多年来一直支持窗口函数。
猜你喜欢
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-24
  • 2017-11-05
  • 1970-01-01
  • 2017-01-01
相关资源
最近更新 更多