Sql 聚合选择中最大值的计数
我想计算一个特定字段中最大值和最小值的个数 如果要取消对行的注释,此选择将被中断:Sql 聚合选择中最大值的计数,sql,sql-server,Sql,Sql Server,我想计算一个特定字段中最大值和最小值的个数 如果要取消对行的注释,此选择将被中断: 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(c
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个以上的独特值,但在这一点上,我想解决这个问题,因为它具有学术价值。我也知道我可以通过一个子选择来解决这个问题,但我一直在等待一个优雅的解决方案。如果您使用支持string\u agg的sql server,则可以执行以下操作 这是一个db fiddble链接 如果你想通过clientnumber显示那些有两个或更多clientname的,那么 在having子句中添加以下内容
having(charindex(';',string_agg(concat(clientname,'-',cnt),';')))<>0
如果您使用的是支持string_agg的sql server,则可以执行以下操作 这是一个db fiddble链接 如果你想通过clientnumber显示那些有两个或更多clientname的,那么 在having子句中添加以下内容
having(charindex(';',string_agg(concat(clientname,'-',cnt),';')))<>0
如果您知道有两个名称,则无需子选择即可执行此操作:
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)
还有一个
事实上,这并不坏。它通过名称列和客户机进行聚合,使用窗口函数将所有数据放在一行上,然后选择一行。在“排序方式”中有一个小技巧,即只选择具有多个名称的客户端。如果您知道有两个名称,则无需再次选择即可:
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)
还有一个
事实上,这并不坏。它通过名称列和客户机进行聚合,使用窗口函数将所有数据放在一行上,然后选择一行。
order by
中有一个小技巧,只选择具有多个名称的客户端。因为你不能嵌套聚合函数,你几乎必须使用CTE
或子查询。@Nick是的,你说得对,但我很惊讶一些聪明人能想出优雅的解决方案。我认为CTE不会太糟糕。“sql server的最新版本”没有用。你能编辑这个问题吗?添加一些示例数据和期望的结果会很有帮助。看起来你得到的答案没有子查询,可以处理两个唯一的值…因为你不能嵌套聚合函数,你几乎必须使用CTE
或子查询。@Nick是的,你是对的,但我喜欢惊讶于一些聪明人能想出优雅的解决方案。我认为CTE不会太糟糕。“sql server的最新版本”没有什么用处。你能编辑这个问题吗?添加一些示例数据和期望的结果会很有帮助。看起来你得到了一个没有子查询的答案,这将适用于两个唯一的值…这很有趣,很难看,但很有趣。我确信每次尝试使用嵌套聚合(甚至使用窗口函数)时都会出错。现在我需要回去重新讨论一些问题。遗憾的是,它对两个以上的名字不起作用。@Nick。也许可以将它推广到更多的名字,但OP特别询问了两个名字。是的,我只关心两个样本,因为这是一个反复的清理,由一个人决定使用哪个名字。当计数(*)大于2时,他们会知道要挖得更深一点。这很有趣,很难看,但很有趣。我确信每次尝试使用嵌套聚合(甚至使用窗口函数)时都会出错。现在我需要回去重新讨论一些问题。遗憾的是,它对两个以上的名字不起作用。@Nick。也许可以将它推广到更多的名字,但OP特别询问了两个名字。是的,我只关心两个样本,因为这是一个反复的清理,由一个人决定使用哪个名字。当计数(*)大于2时,他们会知道要挖得更深一些。