Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 聚合选择中最大值的计数_Sql_Sql Server - Fatal编程技术网

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时,他们会知道要挖得更深一些。