【问题标题】:sql using Aggregates using a combination of min(), count(), having clausesql using Aggregates 使用 min()、count()、have 子句的组合
【发布时间】:2019-04-17 00:23:10
【问题描述】:

试图找到允许我按组计算名字的代码,然后返回计数最少的名字。

样本数据:-

PersonGroup   FirstName
------------------------
A             Bob
A             Mary
A             Bob
A             Bob
B             Michelle
B             Michelle
B             Greg
B             Greg
B             Michelle
C             Cindy
C             Michelle
C             Michelle
D             Rod
D             Rod
D             Rod
D             Rod
D             Rod
D             Mary
D             Mary
D             Mary
D             Mary
D             Mary
D             Mary

需要输出:

PersonGroup   FirstName    Count
--------------------------------
    A         Mary           1
    B         Greg           2
    C         Cindy          1
    D         Rod            5

First Name 列的名称在组中出现最少

Count 列包含每组出现次数最少的 Name 计数

这是我目前的代码,但是每个名字都会被返回,

select
    PersonType,
    FirstName,
    count (firstName) as mycount
from
    [Person].[Person]
group by 
    FirstName,
    [PersonType]
having 
    count(firstName) = (select min(a.cnt)
                        from 
                             (select count(firstname) as cnt 
                              from [Person].[Person] 
                              group by [FirstName]) as a)
order by 
    PersonType desc

【问题讨论】:

  • 领带呢?例如,如果一个组的两个(或多个)名称只出现一次,你想返回什么?
  • 对于 SQL 问题,您应该始终标记您的 DBMS。非标准括号看起来像 SQL Server。这是您使用的 DBMS 吗?
  • 样本数据不佳。删除 (B, Michelle) 行中的一个,让它变得更棘手! (并相应地调整预期结果。)

标签: sql count min having


【解决方案1】:

你可以使用 row_number()

select a.*
from (select PersonType,FirstName ,count (firstName) as mycount, 
             row_number() over (partition by PersonType order by count(*)) as rn
      from [Person].[Person]
     group by FirstName,[PersonType]
     ) a
where rn= 1; 

【讨论】:

  • 在第二种方法中,对所有行使用 row_number 行号将为 1 。您需要从 over 子句中删除 firstname 分区,然后它将正常工作
  • 不要使用第一个,它会多次解析整个表。没有必要。第一个答案是一个糟糕的答案。然而,第二个答案是完美的:)
【解决方案2】:

使用窗口函数row_number()

    with cte as
(
  select 'A' as PersonGroup, 'Bob' as name
  union all
  select 'A', 'Mary'
   union all
  select 'A', 'Mary'
    union all
  select 'B', 'Michelle'  
    union all
  select 'B', 'Greg'  
     union all
  select 'B', 'Greg' 
    union all
  select 'B', 'Michelle'
     union all
  select 'B', 'Michelle'
    union all
  select 'C', 'Michelle'
     union all
  select 'C', 'Michelle'
     union all
  select 'C', 'Cindy'
     union all
  select 'D', 'Rod'  
     union all
  select 'D', 'Rod'  
     union all
  select 'D', 'Rod'
    union all
  select 'D', 'Rod'  
     union all
  select 'D', 'Rod'
     union all
  select 'D', 'Mary'
     union all
  select 'D', 'Mary'
     union all
  select 'D', 'Mary'
     union all
  select 'D', 'Mary'
     union all
  select 'D', 'Mary'
     union all
  select 'D', 'Mary'
)
 , cte3 as (
  select personGroup, name, COUNT(*) as cnt, row_number() over(partition by PersonGroup order by COUNT(*) ) rn  from cte GROUP BY personGroup, name
      ) select PersonGroup,name,cnt from cte3 where rn=1

demo link

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 2011-06-23
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多