按组分组的最大COUNT数以及加入EQUALS和NOT EQUALS条件

时间:2017-03-30 16:18:51

标签: sql sql-server performance common-table-expression

我正在开发一个场景,我需要根据UserID获取计数,然后获取从分组结果集中获得的最大计数。

然后,这个最大计数将用于计算从分组结果集中获得的每一行的百分比。

以下是一个例子:

这是我的样本数据:

 Users Table:   
  UserID        CountAsApproved  
    1                   1
    2                   1   
    1                   1
    2                   1
    3                   1
    3                   0
    4                   1
    1                   1
    4                   0

    Grouping Result:

  UserID            Counts
    1                 3
    2                 2
    3                 1
    4                 1

然后我需要获得最大计数(在这种情况下,最大计数为3) 然后按如下方式计算百分比:

 UserID         Counts      MaxCount            Percentage
    1             3           3            (Count/MaxCount)*100
    2             2           3                 2/3 * 100
    3             1           3                 1/3 * 100
    4             1           3                 1/3 * 100

我目前有这样的查询:

    ;WITH Groups_CTE AS(
        SELECT UserID, COUNT(CountAsApproved) as Counts
        FROM Users 
        GROUP BY UserID),
MaxCount_CTE AS 
(
        SELECT MAX(Counts) AS MaxCount
        FROM Groups_CTE
)
SELECT 
        gc.UserID,
        gc.Counts,
        mc.MaxCount,
        CASE WHEN CAST(( ( gc.Counts
                                   / mc.MaxCount ) * 100 ) AS INT) = 0
                     THEN 1
                     ELSE CAST(( ( gc.Counts
                                   / mc.MaxCount ) * 100 ) AS INT)
                END AS Percentage
FROM    Groups_CTE gc CROSS JOIN MaxCount_CTE mc

当我在以下条件下进行内部联接而不是CROSS JOIN时,上面的查询产生相同的结果

FROM    Groups_CTE gc JOIN MaxCount_CTE mc
ON gc.Counts <> mc.MaxCount OR gc.Counts = mc.MaxCount

我只想检查在性能观点或减少代码行数方面是否有更好的方法。我使用任何一个连接得到了相同的结果,当我使用CROSS APPLY时没有条件。 我对使用两个CTE也有点犹豫。

让我知道您在即兴创作此代码时的想法和建议。

  

如果它有帮助,我们执行这些操作的Users表可能包含数千行。

3 个答案:

答案 0 :(得分:2)

使用max() over()

select 
    userid
  , Counts     = sum(countasapproved)
  , MaxCount   = max(sum(countasapproved)) over()
  , Percentage = sum(countasapproved+.0)/max(sum(countasapproved)) over()
from Users 
group by userid

rextester演示:http://rextester.com/TLG73597

返回:

+--------+--------+----------+------------+
| userid | Counts | MaxCount | Percentage |
+--------+--------+----------+------------+
|      1 |      3 |        3 | 1,000000   |
|      2 |      2 |        3 | 0,666666   |
|      3 |      1 |        3 | 0,333333   |
|      4 |      1 |        3 | 0,333333   |
+--------+--------+----------+------------+

答案 1 :(得分:1)

在汇总结果上使用窗口函数:

select 
  userid, 
  sum(countasapproved) as counts, 
  max(sum(countasapproved)) over () as maxcount,
  sum(countasapproved) * 100.0 / max(sum(countasapproved)) over () as percentage
from users
group by userid;

答案 2 :(得分:0)

根据数据的数量,子查询可能会更高效

Select *
      ,MaxCount = max(Cnt) over ()
      ,PctCnt   = (Cnt+0.0) / max(Cnt) over ()
 From  (
        Select UserID
              ,Cnt = sum(CountAsApproved)
         From YourTable 
         Group By UserID
       ) A

返回

UserID  Cnt MaxCount    PctCnt
1       3   3           1.000000000000
2       2   3           0.666666666666
3       1   3           0.333333333333
4       1   3           0.333333333333