[英]Count of the max value in an aggregate select
我想计算特定字段中最小值的最大值的数量。
如果我取消注释这些行,则此 select 已损坏:
select clientnumber
,count(distinct clientname) as NumberUnique
,max(clientname) as UniqueSample1
-- ,sum(case clientname when min(clientname) then 1 else 0 end) as UniqueCount1
,min(clientname) as UniqueSample2
-- ,sum(case clientname when min(clientname) then 1 else 0 end) as UniqueCount2
FROM dbo.InvoicesSent dt
group by clientnumber
having count(distinct clientname) > 1
背景:我们正在审查同一客户编号的发票上有两个不同名称的记录。 知道两者中哪一个的计数更高有助于分析。
注意:我知道还有其他解决方案可以考虑超过 2 个唯一值,但在这一点上,我想解决这个问题的学术价值。 我也知道我可以通过子选择来解决这个问题,但我坚持要一些优雅的解决方案。
如果您知道有两个名称,那么您可以在没有子选择的情况下执行此操作:
select top (1) with ties clientnumber,
min(clientname) over (partition by clientnumber) as min_name,
max(clientname) over (partition by clientnumber) as max_name,
(case when clientname = min(clientname) over (partition by clientnumber)
then count(*)
else sum(count(*)) over (partition by clientnumber) - count(*)
end) as min_count,
(case when clientname = max(clientname) over (partition by clientnumber)
then count(*)
else sum(count(*)) over (partition by clientnumber) - count(*)
end) as max_count
from InvoicesSent i
group by clientnumber, clientname
order by row_number() over (partition by clientnumber order by clientname) +
(case when min(clientname) over (partition by clientnumber) = max(clientname) over (partition by clientnumber) then 1 else 0 end);
我并不是说这很优雅。 只是根据您的条件是可能的。
这是一个稍微简单的形式:
select top (1) with ties clientnumber,
clientname as min_name,
max(clientname) over (partition by clientnumber) as max_name,
count(*) as min_count,
sum(count(*)) over (partition by clientnumber) - count(*) max_count
from InvoicesSent i
group by clientnumber, clientname
order by row_number() over (partition by clientnumber order by clientname) +
(case when count(*) over (partition by clientnumber) >= 2 then 0 else 1 end)
还有一个db<>fiddle 。
其实,这并没有那么糟糕。 它按名称列和客户端聚合,使用 window 函数将所有数据放在一行上,然后选择一行。 仅对具有多个名称order by
有一个小技巧。
如果您正在使用支持 string_agg 的 sql 服务器,则可以执行以下操作
这是一个 db fiddle 链接https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=4184c994d37e0dc7178212cd657ba15f
create table invoices(id int identity, clientnumber int, clientname varchar(100));
insert into invoices(clientnumber,clientname)
select t.clientnumber,clientname
from (values(100,'Adam')
,(100,'Adam')
,(100,'Abraham')
,(101,'Grace')
,(101,'Grace')
,(102,'Paul')
)t(clientnumber,clientname);
select clientnumber
,string_agg(concat(clientname,'-',cnt),';') as clientname_and_cnt
from(
select distinct
clientnumber
,clientname
,count(*) over(partition by clientnumber,clientname) as cnt
from invoices
)x
group by clientnumber
order by 2 desc
Output
+--------------+--------------------+
| clientnumber | clientname_and_cnt |
+--------------+--------------------+
| 102 | Paul-1 |
| 101 | Grace-2 |
| 100 | Abraham-1;Adam-2 |
+--------------+--------------------+
如果你想通过 clientnumber 显示那些有两个或多个客户名的,那么在 having 子句中添加以下内容
having(charindex(';',string_agg(concat(clientname,'-',cnt),';')))<>0
如果您想根据客户名称的发票数量订购,那么您也可以执行以下操作(在组子句中)
select clientnumber
,string_agg(concat(clientname,'-',cnt),';') within group(order by cnt desc) as clientname_and_cnt
from(
select distinct
clientnumber
,clientname
,count(*) over(partition by clientnumber,clientname) as cnt
from invoices
)x
group by clientnumber
order by 2 desc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.