首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用两个或多个分组列选择出现频率最高的记录

使用两个或多个分组列选择出现频率最高的记录
EN

Stack Overflow用户
提问于 2009-07-30 16:31:54
回答 4查看 6.4K关注 0票数 1

我有一个没有主键的表,我不能添加主键--表中的相关列是:

代码语言:javascript
运行
复制
Department   | Category  | 
-------------+-----------+
0001         | A         |
0002         | D         |
0003         | A         | 
0003         | A         |
0003         | C         |
0004         | B         |

我希望为每个Department检索一行,这将为我提供部门代码和表中出现频率最高的Category

代码语言:javascript
运行
复制
Department   | Category  | 
-------------+-----------+
0001         | A         |
0002         | D         |
0003         | A         | 
0004         | B         |

实现这一目标的最佳方法是什么?我目前的尝试涉及到一个子查询中的一个Count(Category),然后从该子查询中提取Max(CountofCategory),但是在这个阶段包括Category字段意味着返回的行太多(因为GROUP BY既应用于Category级别,也应用于Department)。在平局的情况下,我只需任意选择类别的最小/最大值。理想情况下,这应该是与数据库无关的,但很可能运行在Oracle或MySQL上。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-07-30 16:59:40

在Oracle和SQL Server中都能工作,我相信都是标准的SQL,从后来的标准:

代码语言:javascript
运行
复制
with T_with_RN as
    (select Department
        , Category
        , row_number() over (partition by Department order by count(*) Desc) as RN
    from T
    group by Department, Category)
select Department, Category
from T_with_RN
where RN = 1

编辑我不知道我为什么使用,使用内联视图可能更容易阅读解决方案:

代码语言:javascript
运行
复制
select Department, Category
from (select Department
    , Category
    , row_number() over (partition by Department order by count(*) Desc) as RN
    from T
    group by Department, Category) T_with_RN
where RN = 1

结束编辑

测试用例:

代码语言:javascript
运行
复制
create table T (
    Department varchar(10) null,
    Category varchar(10) null
);

-- Original test case
insert into T values ('0001', 'A');
insert into T values ('0002', 'D');
insert into T values ('0003', 'A');
insert into T values ('0003', 'A');
insert into T values ('0003', 'C');
insert into T values ('0004', 'B');
-- Null Test cases:
insert into T values (null, 'A');
insert into T values (null, 'B');
insert into T values (null, 'B');
insert into T values ('0005', null);
insert into T values ('0005', null);
insert into T values ('0005', 'X');
-- Tie Test case
insert into T values ('0006', 'O');
insert into T values ('0006', 'P');
票数 3
EN

Stack Overflow用户

发布于 2017-02-13 16:26:12

您也可以尝试执行以下操作。此处的窗口将返回类别,这些类别按每个部门的匹配频率从高到低排序。FIRST_VALUE()从中选取第一个。

代码语言:javascript
运行
复制
SELECT DISTINCT (department), 
  FIRST_VALUE(category) OVER
    (PARTITION BY department ORDER BY count(*) DESC ROWS UNBOUNDED PRECEDING)
FROM T
GROUP BY department, category;
票数 1
EN

Stack Overflow用户

发布于 2009-07-30 16:57:09

如果你比我更善于使用子查询,你必须清理一下,但在我的测试中,这产生了你想要的结果:

代码语言:javascript
运行
复制
SELECT
  main.Department as Department,
  (SELECT 
     Category
   FROM yourtable
   WHERE Department=main.Department
   GROUP BY Category
   ORDER BY COUNT(Category) DESC
   LIMIT 1) AS Category
FROM yourtable main
GROUP BY main.Department

诀窍就是使子查询中的一行通过ORDER BY和"LIMIT 1“返回您想要的最大值

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1207753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档