MySQL:优化答案查找表中最常出现的值

时间:2015-03-05 13:23:21

标签: mysql

昨天发布在:

MySQL: Finding most frequently occuring values in table

但是想知道是否有办法改进答案,因为你不应该在最后重复代码来获得MAX(COUNT)

问题

我有两张桌子:

购买:

item
001
003
002
001
002
004
003
001
002

项目:

id    |   name
001   |   Item 1
002   |   Item 2
003   |   Item 3
004   |   Item 4

预期产出:

item     name
001      Item 1
002      Item 2

我需要找到购买表中最常出现的(多个)项目,并输出项目的名称。我的查询应该包含哪些内容?

答案我到目前为止

SELECT t.cnt, t.name FROM 
 (SELECT COUNT(*) AS "cnt", item.name 
  FROM purchases 
  LEFT JOIN item ON item.id = purchases.item 
  GROUP BY item.name) t
WHERE t.cnt = (SELECT MAX(t2.cnt) FROM 
 (SELECT COUNT(*) AS "cnt"
   FROM purchases 
   LEFT JOIN item ON item.id = purchases.item 
   GROUP BY item.name) t2
 )

3 个答案:

答案 0 :(得分:1)

您必须先获取最大数量,然后使用它来过滤匹配的项目:

SELECT   i.*
FROM     purchases p
    JOIN item i ON i.id = p.item
GROUP BY i.id
HAVING   COUNT(*) = (
           SELECT   COUNT(*)
           FROM     purchases
           GROUP BY item
           ORDER BY COUNT(*) DESC
           LIMIT    1
         )

请注意,此查询依赖id作为item表的PK(或至少在其中唯一),原因有两个:

  1. 确保JOIN不会对外部查询中的COUNT(*)产生负面影响;以及

  2. 它使您能够确定从*中选择item尽管进行了分组操作(其他RDBMS平台不允许这样做,但需要您对每个非聚合的分组)输出列 - 但是MySQL提供了这个"功能"作为性能改进)。

答案 1 :(得分:0)

试试这个:

SELECT I.`id` AS id, COUNT(I.`id`) AS `id_count`, P.`name` AS name
FROM `item` I
JOIN `purchases` P
ON I.`id` = P.`id`
ORDER BY COUNT(I.`id`) DESC
GROUP BY I.`id`

预期产出:

|-------|-------------|--------------------|
|   id  | id_count    |     name          |
|-------|-------------|-------------------|
| 101   |     5       |     Item 1        |
| 102   |     6       |     Item 2        |
| 103   |     8       |     Item 3        |
| 104   |     12      |     Item 4        |
...
|------------------------------------------|

答案 2 :(得分:0)

我相信这样的事情可行。你可以使用'和'按顺序排列获得最佳成绩。

SELECT count(p.item), i.name
FROM purchases p, item i
WHERE p.item = i.id
GROUP BY p.item HAVING count(p.item) > 1
ORDER BY count(p.item) DESC;

您可以选择添加' LIMIT 1'到最后。