SQL 将值除以总和,分组
SQL Divide values by a total sum, groupwise
我有一个 table 喜欢:
user_id operation amount
1 purchase 10
1 sale 40
2 purchase 100
2 sale 20
2 conversion 15
3 sale 70
4 conversion 40
由 SQL 查询给出:
SELECT
user_id,
operation,
COUNT(item_num) AS amount
FROM MyTable
GROUP BY user_id, operation
我想为每个用户计算每个操作占总金额的百分比,最好将它们放在列中(实际上是除以数字):
user_id purchase sale conversion
1 10 /50 40 /50 0 /50
2 100 /135 20 /135 15 /135
3 0 /70 70 /70 0 /70
4 0 /40 0 /40 40 /40
编辑:
由于回复中给出的直觉,我能够找到最适合我的解决方案
WITH result
AS
(
SELECT
[user_id],
[operation],
CAST(COUNT([item_num]) AS float) AS amount,
SUM(COUNT([item_num])) over(partition by [user_id]) AS total_amount
FROM Mytable
GROUP BY user_id, operation
)
SELECT
[user_id],
ROUND(ISNULL([purchase], 0) / total_amount, 2) AS purchase,
ROUND(ISNULL([sale], 0) / total_amount, 2) AS sale,
ROUND(ISNULL([conversion], 0) / total_amount, 2) AS conversion
FROM result
PIVOT
(
MAX(amount)
FOR operation IN ([purchase], [sale], [conversion])
) x
ORDER BY user_id
此代码适合您。您将需要使用带有列的 CTE 和 sum() over() 来计算每个 user_id 的总和。
有了这些信息,您需要做的就是调整结果并提供所需的格式。如果您需要除法而不仅仅是显示它的除法,请删除格式和连接。
WITH Sum_Over AS
(
select user_id,operation, amount,sum(amount) over(partition by user_id) AS Total_Sum
from #test
)
SELECT user_id
,CAST(ISNULL([purchase],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [purchase]
,CAST(ISNULL([sale],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [sale]
,CAST(ISNULL([conversion],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [conversion]
FROM Sum_Over
PIVOT (
max(amount)
FOR operation IN ([purchase],[sale],[conversion])
)x
ORDER BY user_id
Jader 的回答更清晰。这个使用分组依据:
With result As
(
SELECT
user_id,
Sum(amount) as tot,
Case When operation = 'purchase' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [purchase],
Case When operation = 'sale' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [sale],
Case When operation = 'conversion' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [conversion]
FROM MyTable x
GROUP BY user_id, operation
)
Select user_id,
isnull(Max(purchase),'0/' + convert(nVarChar(50),sum(tot))) As purchase,
isnull(Max(sale),'0/' + convert(nVarChar(50),sum(tot))) As sale,
isnull(Max(conversion),'0/' + convert(nVarChar(50),sum(tot))) As conversion
From result
Group By user_id
我有一个 table 喜欢:
user_id operation amount
1 purchase 10
1 sale 40
2 purchase 100
2 sale 20
2 conversion 15
3 sale 70
4 conversion 40
由 SQL 查询给出:
SELECT
user_id,
operation,
COUNT(item_num) AS amount
FROM MyTable
GROUP BY user_id, operation
我想为每个用户计算每个操作占总金额的百分比,最好将它们放在列中(实际上是除以数字):
user_id purchase sale conversion
1 10 /50 40 /50 0 /50
2 100 /135 20 /135 15 /135
3 0 /70 70 /70 0 /70
4 0 /40 0 /40 40 /40
编辑: 由于回复中给出的直觉,我能够找到最适合我的解决方案
WITH result
AS
(
SELECT
[user_id],
[operation],
CAST(COUNT([item_num]) AS float) AS amount,
SUM(COUNT([item_num])) over(partition by [user_id]) AS total_amount
FROM Mytable
GROUP BY user_id, operation
)
SELECT
[user_id],
ROUND(ISNULL([purchase], 0) / total_amount, 2) AS purchase,
ROUND(ISNULL([sale], 0) / total_amount, 2) AS sale,
ROUND(ISNULL([conversion], 0) / total_amount, 2) AS conversion
FROM result
PIVOT
(
MAX(amount)
FOR operation IN ([purchase], [sale], [conversion])
) x
ORDER BY user_id
此代码适合您。您将需要使用带有列的 CTE 和 sum() over() 来计算每个 user_id 的总和。 有了这些信息,您需要做的就是调整结果并提供所需的格式。如果您需要除法而不仅仅是显示它的除法,请删除格式和连接。
WITH Sum_Over AS
(
select user_id,operation, amount,sum(amount) over(partition by user_id) AS Total_Sum
from #test
)
SELECT user_id
,CAST(ISNULL([purchase],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [purchase]
,CAST(ISNULL([sale],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [sale]
,CAST(ISNULL([conversion],0) AS VARCHAR(5))+'/'+CAST(Total_Sum AS VARCHAR(5)) AS [conversion]
FROM Sum_Over
PIVOT (
max(amount)
FOR operation IN ([purchase],[sale],[conversion])
)x
ORDER BY user_id
Jader 的回答更清晰。这个使用分组依据:
With result As
(
SELECT
user_id,
Sum(amount) as tot,
Case When operation = 'purchase' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [purchase],
Case When operation = 'sale' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [sale],
Case When operation = 'conversion' Then
convert(nvarchar(5),sum(amount)) + '/' + convert(nVarChar(50),(Select sum(amount) From MyTable t Where t.user_id = x.user_id))
End As [conversion]
FROM MyTable x
GROUP BY user_id, operation
)
Select user_id,
isnull(Max(purchase),'0/' + convert(nVarChar(50),sum(tot))) As purchase,
isnull(Max(sale),'0/' + convert(nVarChar(50),sum(tot))) As sale,
isnull(Max(conversion),'0/' + convert(nVarChar(50),sum(tot))) As conversion
From result
Group By user_id