mySQL 按类别获取最常见项目的示例

mySQL get an example of the the most common item by category

我有一个table喜欢

id category   item
1  candy      bar
2  candy      gum
3  candy      bar
4  candy      gummy
5  candy      cupcake
6  vegetable  carrot
7  vegetable  pea
8  vegetable  pea
9  meat       beef
10 meat       pork
11 meat       chicken
12 meat       chicken

我打算构建一个 mysql/maridb 查询,该查询为我提供每个类别的总数和 returns 每个类别中最常见的项目

category     example   total
candy        bar       5
vegetable    pea       3
meat         chicken   4

您可以使用基本聚合获得 categorytotal

select i.category, count(*) as total
from items i
group by category;

为了获得最常见的项目,我会在 SELECT 子句中使用带有 LIMIT 1 的相关子查询:

select i.category, count(*) as total, (
    select i1.item
    from items i1
    where i1.category = i.category
    group by i1.item
    order by count(*) desc
    limit 1
) as example
from items i
group by category;

演示:http://rextester.com/ICK46600

请注意,您可能需要添加一些逻辑来处理平局。例如 - 如果你想获得第一个出现的项目,你可以将 ORDER BY 子句更改为

order by count(*) desc, min(i1.id) asc

试试这个:-

Select a.category, b.item as example, a.total
from

(
Select category, count(*) as total
from Your_Table_Name
GROUP BY category
) a

inner join

(
  Select a.category, a.item, cnt_item from
      (
        SELECT category, item, count(*) as cnt_item
        from Your_Table_Name
        group by category, item
      ) a
  inner join
   (
    Select category,max(cnt_item) as max_rep
    from
        (
        SELECT category, item, count(*) as cnt_item
        from Your_Table_Name
        group by category, item
        ) a
    group by category
   ) b
  on a.category=b.category and a.cnt_item=b.max_rep 
) b
on a.category=b.category;

如果您有任何问题,请告诉我。

我相信这应该有效:

 ;WITH CTE AS (
    SELECT category
         , item
         , count(item) as NumItems
         , dense_rank() over (partition by category order by count(item) desc) as ItemRank
    FROM yourtable
    GROUP BY category, item)

  SELECT * from CTE WHERE ItemRank = 1

SQL Fiddle

通常我讨厌 select 语句中的 select;但这在编码子查询和 MySQL 中缺少分析函数时会产生大量开销,并且所有事情都有时间和地点。这个好像很好用

SELECT A.Category, (SELECT ITEM 
                    FROM TABLE B 
                    WHERE B.Category = A.Category 
                    GROUP BY ITEM 
                    ORDER BY COUNT(1) DESC, ITEM 
                    LIMIT 1) as Example
     , count(*) as Total
FROM TABLE A
GROUP BY A.Category

试试这个代码:

WITH CTE AS ( SELECT category , item , 
count(item) as NumItems , 
dense_rank() over (partition by category order by count(item) desc) as ItemRank FROM items GROUP BY category, item)

select a.category,item,total from (SELECT * from CTE WHERE ItemRank = 1)a
left join 
(select category, count(*) total
from items
group by category)b
on b.category=a.category

这采用了不同的方法,并使用了高效的 groupwise-max .

SELECT
    category,
    item AS example, 
    ( SELECT COUNT(*) FROM items1  WHERE category = x.category ) AS total
FROM
  ( SELECT  @prev := '' ) AS init
JOIN
  ( SELECT  category != @prev AS first,
            @prev := category,
            category, item, ct
        FROM  ( SELECT category, item, COUNT(*) AS ct
                 FROM items1
                 GROUP BY category, item
                 ORDER BY category, item ) AS b
        ORDER BY
            category, ct DESC
  ) x
WHERE  first
ORDER BY  category  ;

如果没有更大的数据集,很难说比 Paul 的解决方案运行得更快还是更慢。这可能取决于您使用的 MySQL 版本。