我正在开发一个场景,我需要根据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表可能包含数千行。
答案 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