我有一个没有主键的表,我不能添加主键--表中的相关列是:
Department | Category |
-------------+-----------+
0001 | A |
0002 | D |
0003 | A |
0003 | A |
0003 | C |
0004 | B |我希望为每个Department检索一行,这将为我提供部门代码和表中出现频率最高的Category。
Department | Category |
-------------+-----------+
0001 | A |
0002 | D |
0003 | A |
0004 | B |实现这一目标的最佳方法是什么?我目前的尝试涉及到一个子查询中的一个Count(Category),然后从该子查询中提取Max(CountofCategory),但是在这个阶段包括Category字段意味着返回的行太多(因为GROUP BY既应用于Category级别,也应用于Department)。在平局的情况下,我只需任意选择类别的最小/最大值。理想情况下,这应该是与数据库无关的,但很可能运行在Oracle或MySQL上。
发布于 2009-07-30 16:59:40
在Oracle和SQL Server中都能工作,我相信都是标准的SQL,从后来的标准:
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编辑我不知道我为什么使用,使用内联视图可能更容易阅读解决方案:
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结束编辑
测试用例:
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');发布于 2017-02-13 16:26:12
您也可以尝试执行以下操作。此处的窗口将返回类别,这些类别按每个部门的匹配频率从高到低排序。FIRST_VALUE()从中选取第一个。
SELECT DISTINCT (department),
FIRST_VALUE(category) OVER
(PARTITION BY department ORDER BY count(*) DESC ROWS UNBOUNDED PRECEDING)
FROM T
GROUP BY department, category;发布于 2009-07-30 16:57:09
如果你比我更善于使用子查询,你必须清理一下,但在我的测试中,这产生了你想要的结果:
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“返回您想要的最大值
https://stackoverflow.com/questions/1207753
复制相似问题