根据最大分类出现次数过滤表

时间:2018-09-01 19:00:48

标签: sql greatest-n-per-group

我有如下三列表格

| Category  | Author      | Sales     |
+++++++++++++++++++++++++++++++++++++++
| NW        | account-1   | 10        |
| NW        | account-2   | 20        |
| NW        | account-3   | 30        |
| S         | account-4   | 10        |
| S         | account-5   | 50        |
| S         | account-6   | 55        |

我想生成另一个具有每个类别最大值的表,所需的表应如下所示。

| Category  | Author      | Sales     |
+++++++++++++++++++++++++++++++++++++++
| NW        | account-3   | 30        |
| S         | account-6   | 55        |

我的编码试验

SELECT Category, Author, MAX(Sales)
FROM table
GROUP BY Category, Author

我不确定MAX()聚合失败的原因(上面的代码)。如果有人详细解释原因并提供简单有效的解决方案,将不胜感激。

6 个答案:

答案 0 :(得分:1)

我为此建议一个相关的子查询:

select t.*
from t
where t.sales = (select max(t2.sales) from t t2 where t2.category = t.category);

特别是,几乎所有数据库都会利用(category, sales)上的索引(如果有)来优化此查询。

查询的问题是您同时按categoryauthor进行聚合。您希望在category中获得最大的销售额。并且您希望作者具有最高的销售额。这不同于max(author)或按author进行汇总。

答案 1 :(得分:1)

由于Group by是一个组,因此,当您使用GROUP BY Category, Author时,您需要按group byCategory列中的Author,因此有六个组

查询

select Category,Author
from t
group by Category,Author

结果

| Category |    Author |
|----------|-----------|
|       NW | account-1 |
|       NW | account-2 |
|       NW | account-3 |
|        S | account-4 |
|        S | account-5 |
|        S | account-6 |

但是如果我们只做group by Category,则有两个组。

查询

select Category
from t
group by Category

[结果]

| Category |
|----------|
|       NW |
|        S |

因此,您可以尝试获取MAX销售列group by Category,然后加入Sales和Category或与之建立联系

CREATE TABLE T(
    Category varchar(5),
    Author varchar(50),
    Sales int
);


insert into t values ('NW','account-1', 10);
insert into t values ('NW','account-2', 20);
insert into t values ('NW','account-3', 30);
insert into t values ('S','account-4', 10);
insert into t values ('S','account-5', 50);
insert into t values ('S','account-6', 55);

查询1

select * from t t1 where exists(
  SELECT 1
  FROM T tt
  WHERE t1.Category = tt.Category
  GROUP BY tt.Category
  HAVING MAX(tt.Sales) = t1.Sales
)

Results

| Category |    Author | Sales |
|----------|-----------|-------|
|       NW | account-3 |    30 |
|        S | account-6 |    55 |

答案 2 :(得分:1)

要解决您的问题,您需要一个子查询

说明:您的当前解决方案不起作用,因为您不过滤针对max(Sales)的原始查询,而只是问“此商品的最高销售额是多少类别?”。因此,您需要另一个子查询,

  1. 找出每个类别的最大销售额,所以
  2. 然后,您可以根据作者和类别的组合来过滤原始表格,该组合的销售数量与每个类别的最大销售数量相同。

以下代码应正常工作:

SELECT tbl_sales.Category, tbl_sales.Author, tbl_sales.Sales
FROM tbl_sales
JOIN(
    SELECT Category, MAX(Sales) MaxSales
    FROM tbl_sales
    GROUP BY Category
    ) tbl_maxsales
ON tbl_sales.Sales = tbl_maxsales.MaxSales

您可以找到a SQL fiddle implementation here
(我假设使用MySQL 5.6,但这不应起很大作用)

如果您有任何疑问或需要更多指导,请随时向我发送消息或发表评论。

答案 3 :(得分:0)

max()不会失败..您正在按类别,作者进行分组,因此yoru查询返回表中类别和作者之间每种组合的最大销售额。 ..如果您需要与最大销售相关的类别相关的行,则可以在最大结果子查询上使用内部联接

  select * from my_table m
  inner join (

  select category, max(sales) max_sales
  from  my_table  
  group by category 



  ) t  on t.category  =  m.category and t.max_sales = m.sales 

答案 4 :(得分:0)

请尝试以下声明

SELECT * from TableName AS T1 WHERE EXISTS(
  SELECT 1
  FROM TableName AS T2
  WHERE T1.Category = T2.Category
  GROUP BY T2.Category
  HAVING MAX(T2.Sales) = T1.Sales)

致谢

答案 5 :(得分:0)

您可以使用此查询获取数据

;WITH query AS (
    SELECT          
        ROW_NUMBER() OVER (PARTITION BY  Category  ORDER BY Sales DESC) AS [Index],
        Category,
        Sales 
    FROM 
        table
)

SELECT * FROM query WHERE [Index] = 1