MySQL:使用COUNT()从子查询中选择MAX()

时间:2013-08-05 06:22:47

标签: mysql sql aggregate-functions

在将此标记为重复之前,请先查看此SQLFiddle

我有这个架构:

CREATE TABLE book(book_id int,
                   book_name varchar(100),
                   author_id int,
                   editor_id varchar(100),
                   isbn varchar(100));
INSERT INTO book
VALUES
(1 , 'Book1 Title' ,  12  ,  'Editor1'   , '8000-9000' ),
(2 , 'Book2 Title' ,  98  ,  'Editor1'   , '8000-9001' ),
(1 , 'Book1 Title' ,  12  ,  'Editor1'   , '8000-9002' ),
(3 , 'Book3 Title' ,  3  ,  'Editor1'   , '8000-9003' );

CREATE TABLE author(author_id int,
                    fn varchar(100),
                    ln varchar(100));
INSERT INTO author
VALUES
(12, 'name1','lname1'),
(98,'name2','lname2'),
(3,'name3','lname3');

子查询:

  SELECT c.author_id,COUNT(*) book_count FROM book c
  GROUP BY c.author_id

有一个结果:

| AUTHOR_ID | BOOK_COUNT |
--------------------------
|         3 |          1 |
|        12 |          2 |
|        98 |          1 |

现在,这里棘手的部分是这个查询的结果:

SELECT MAX(book_count),a.* FROM
author a,(
  SELECT c.author_id,COUNT(*) book_count FROM book c
  GROUP BY c.author_id
) b 
where a.author_id = b.author_id

就是这样:

| MAX(BOOK_COUNT) | AUTHOR_ID |    FN |     LN |
------------------------------------------------
|               2 |         3 | name3 | lname3 |

应该是这样的:

| MAX(BOOK_COUNT) | AUTHOR_ID |    FN |     LN |
------------------------------------------------
|               2 |        12 | name1 | lname1 |

您认为查询有什么问题?

3 个答案:

答案 0 :(得分:3)

您只需使用MAX()代替LIMIT,而不是JOIN。也请改用SELECT book_count,a.author_id,a.fn, a.ln FROM author a JOIN ( SELECT c.author_id,COUNT(*) book_count FROM book c GROUP BY c.author_id ) b ON a.author_id = b.author_id ORDER BY book_count DESC LIMIT 1

| BOOK_COUNT | AUTHOR_ID |    FN |     LN |
-------------------------------------------
|          2 |        12 | name1 | lname1 |

输出:

MAX()

请参阅this SQLFiddle


修改

如果你想使用SELECT book_count,a.author_id,a.fn, a.ln FROM author a JOIN ( SELECT c.author_id,COUNT(*) book_count FROM book c GROUP BY c.author_id ) b ON a.author_id = b.author_id WHERE book_count = (SELECT MAX(book_count) FROM ( SELECT c.author_id,COUNT(*) book_count FROM book c GROUP BY c.author_id ) b ) ,你必须使用这样的子查询:

LIMIT

请参阅this SQLFiddle


<强> EDIT2:

您可以在内部查询中使用SELECT book_count,a.author_id,a.fn, a.ln FROM author a JOIN ( SELECT c.author_id,COUNT(*) book_count FROM book c GROUP BY c.author_id ORDER BY COUNT(*) DESC LIMIT 1 ) b ON a.author_id = b.author_id ,而不是在外部查询中使用{{1}}:

{{1}}

请参阅this SQLFiddle

答案 1 :(得分:1)

事实上,MySQL缺乏对SQL标准的支持,因为它允许使用带有GROUP BY子句的聚合函数并在结果中返回随机数据。你应该避免以这种方式使用聚合。

编辑: 我的意思是,例如在MySQL中你可以像这样执行查询:

SELECT
  MAX(a), b, c
FROM
  table
GROUP BY
  b;

返回c列中的随机数据,这非常错误。

答案 2 :(得分:0)

我想知道这个查询正在运行,你使用了聚合函数而没有使用group by。当您需要识别具有最大角落数的用户时 请尝试

SELECT (book_count),b.author_id FROM
author a

INNER JOIN 
(
 SELECT c.author_id,COUNT(*) book_count FROM book c
 GROUP BY c.author_id) B
ON

 a.author_id = b.author_id
having book_count=MAX(book_count)

让我知道它是否有效。