简体   繁体   English

SQL选择最大值(计数(列A,列B))

[英]SQL Select Max(count( columnA, Column B))

I've been banging my head on this one. 我一直在敲打这个。 I think I'm close. 我想我很亲密。 (Oracle, SQL) (Oracle,SQL)

I've got a table that looks like the following. 我有一张如下表所示的表格。

Company    Code
Apple      A
Google     A
Microsoft  B
Apple      C
Google     B
Microsoft  B
Apple      C
Google     C
Microsoft  B

Each company can resolve to multiple codes. 每家公司都可以解析为多个代码。 What I want to do is create a SQL statement that for each company will give me the company with code that appears the most frequently. 我想要做的是创建一个SQL语句,每个公司都会给公司提供最常出现的代码。 So in my example I'd get 所以在我的例子中,我会得到

Apple      C
Google     <nothing since there's no clear max>
Microsoft  B

What I've put together so far is the following. 我到目前为止所做的是以下内容。 This query returns to me the company with the code that appears the most, however if I have a tie between two codes for a company, I get both back. 这个查询返回给我公司的代码看起来最多,但如果我在一个公司的两个代码之间有一个关系,我会回来。 For Google in my example I'd get (Google, A), (Google, B), (Google, C). 对于我的例子中的Google,我会得到(谷歌,A),(谷歌,B),(谷歌,C)。 I want nothing returned. 我想要什么都不回来。

I believe that I can join the whole thing again with itself and some additional where clauses to filter out the duplicate companies, however I was wondering if there is a better way to do this. 我相信我可以再次加入整个事情和一些额外的where子句来过滤掉重复的公司,但我想知道是否有更好的方法来做到这一点。 What's killing me is the aggregation functions along with the group by since sometimes I get an Oracle single-group group error. 什么杀了我的是聚合函数以及组,因为有时我得到Oracle单组组错误。 Any suggestions are appreciated. 任何建议表示赞赏。

SELECT m1, c.company sp1, b.code ul1 FROM
  (SELECT MAX(c1) m1, company FROM
    (SELECT COUNT(company||code) c1, company, code FROM table GROUP BY company, code ) a
  GROUP BY company) c
left OUTER JOIN
  (SELECT COUNT(company||code) c1, company, code FROM table GROUP BY company, code ) b
ON c.company=b.company and
m1=b.c1;

mj MJ

you can do it with this: 你可以这样做:

select company, case when c > 1 then null else code1 end code1
  from (select company, code1, recs, count(*) over (partition by company, recs ) c, 
           row_number() over (partition by company order by recs desc) rn
  from (select company, code1, count(*) recs
          from table
         group by company, code1))
 where rn = 1
 order by 1

breaking this down: 打破这个:

select company, code1, count(*) recs
 from table
 group by company, code1

this gets us each company with their code count: 这让我们每个公司都有他们的代码数量:

COMPANY   C       RECS
--------- - ----------
Google    A          1
Google    B          1
Microsoft B          3
Apple     A          1
Apple     C          2
Google    C          1

from this we want the most popular. 从这个我们想要最受欢迎。 we do this with an analyic: 我们通过分析来做到这一点:

select company, code1, recs,
       row_number() over (partition by company order by recs desc) rn
  from (select company, code1, count(*) recs
          from t1
         group by company, code1)

giving: 赠送:

COMPANY   C       RECS         RN
--------- - ---------- ----------
Apple     C          2          1 <- we want all rn= "1" rows
Apple     A          1          2
Google    A          1          1<- we want all rn= "1" rows
Google    B          1          2
Google    C          1          3
Microsoft B          3          1<- we want all rn= "1" rows

but now if theres duplicates (as google has)..we count(*) the rows that have RN=1. 但现在如果有重复(如谷歌)...我们计算(*)RN = 1的行。

select company, code1, recs,
       row_number() over (partition by company order by recs desc) rn,
       count(*) over (partition by company, recs ) c
  from (select company, code1, count(*) recs
          from t1
         group by company, code1)

giving

COMPANY   C       RECS         RN          C
--------- - ---------- ---------- ----------
Apple     C          2          1          1
Apple     A          1          2          1
Google    A          1          1          3
Google    B          1          2          3
Google    C          1          3          3
Microsoft B          3          1          1

so we need to say where RN=1 and also c = 1 (ie only ONE row had that number of recs. so we end up with: 所以我们需要说RN = 1和c = 1的位置(即只有一行有recs的数量。所以我们最终得到:

select company, case when c > 1 then null else Code1 end Code1
  from (select company, code1, recs, count(*) over (partition by company, recs ) c, 
           row_number() over (partition by company order by recs desc) rn
  from (select company, code1, count(*) recs
          from t1
         group by company, code1))
 where rn = 1

ie rn = 1 and the c > 1 check is in the case at the top (as we don't want to filter rows out, just mark them as ambiguous. 即rn = 1并且c> 1检查在顶部的情况下(因为我们不想过滤行,只是将它们标记为不明确的。

Try 尝试

with
tcount as
(
select t.company, t.code, count(*) c
from table1 t 
group by t.company, t.code) 

select distinct tt.company,
decode(count(tt.company) over(partition by tt.company),
1,
tt.code,
null)
from tcount tt
where tt.c =
(select max(c) from tcount tti where tt.company = tti.company) 

Here is a fiddle 是一个小提琴

SELECT company,CASE WHEN count_ > 1 THEN NULL ELSE code END
(
SELECT company,MAX(code) code,count(1) count_
(SELECT company,code,rank() OVER(PARTITION BY company ORDER BY count_ DESC) rn FROM
(
select
       company,code,count(1) count_
from   table
group by
       company,code
) 
)
where rn = 1
GROUP BY 
   company
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM