SQL Разделите значения на общую сумму по группам - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть таблица типа:

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

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Ответ от Jader чище.Этот использует Group By:

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
0 голосов
/ 27 ноября 2018

Этот код будет работать для вас.Вам нужно будет использовать 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
...