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

时间:2017-05-03 18:08:19

标签: sql aggregate mariadb

我有一张像

这样的表格
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查询,它给出了每个类别的总数,并返回每个类别中最常见的项目

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

6 个答案:

答案 0 :(得分:1)

您可以使用基本汇总获取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

答案 1 :(得分:1)

我相信这应该有效:

 ;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

答案 2 :(得分:0)

试试这个: -

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;

如果您有任何问题,请与我们联系。

答案 3 :(得分:0)

SQL FIddle

通常我讨厌在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

答案 4 :(得分:0)

试试这段代码:

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

答案 5 :(得分:0)

这采用了不同的方法,并使用了高效的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。