SQL Server Query - groupwise multiplication

后端 未结 3 2031
广开言路
广开言路 2020-11-30 08:31

If we have a table like this:

Grp       Value

Grp1          2
Grp1          5
Grp1          3
Grp2          3
Grp2         -5
Grp2         -2
Grp3                   


        
3条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-30 08:45

    At does annoy me that there is no Multiply / Product aggregate function in SQL server. Unfortunately I didn't find the answer @gbn gave above until I'd already solved the problem a different way. I'm posting this alternative solution just in case it helps anyone, or if it turns out to be more efficient.

    My solution basically involves using a recursive common table expression to multiply all the values together.

    DECLARE @t TABLE (PID INT, ID INT, multiplier DECIMAL(14,5))
    
    INSERT @t
            (PID, ID, multiplier)
    VALUES  (1, 1, 1.5 )
          , (2, 1, 1.2)
          , (3, 2, 1.7)
          , (4, 3, 1)
          , (5, 4, 0.8)
          , (6, 4, 0.5)
          , (7, 4, 2)
          , (8, 4, 0.5)
    
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY PID )
    FROM @t;
    
    
    WITH 
    trn AS
    (
    SELECT PID, ID, multiplier, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY PID ) AS rn
    FROM @t
    ),
    tmu AS 
    (
        SELECT DISTINCT 
            ID, 
            trn.multiplier AS multiplier,
            1 AS Iteration
        FROM trn WHERE rn = 1
        UNION ALL 
        SELECT 
            trn.ID, CAST(tmu.multiplier * trn.multiplier AS DECIMAL(14,5)) AS multiplier
            , tmu.Iteration + 1 AS Iteration
        FROM
            tmu --AS tmu1
            JOIN trn ON tmu.ID = trn.ID AND tmu.Iteration + 1 = trn.rn 
    ),
    mxi AS
    (
        SELECT ID, COUNT(ID) AS Iter
        FROM trn
        GROUP BY ID
    )
    
    SELECT tmu.* 
    FROM tmu 
         JOIN mxi ON mxi.ID = tmu.ID AND mxi.Iter = tmu.Iteration
    ORDER BY ID
    

    Starting table (+ the partitioned row number) selects to:

    PID ID  Multiplier  rn
    1   1   1.50000 1
    2   1   1.20000 2
    3   2   1.70000 1
    4   3   1.00000 1
    5   4   0.80000 1
    6   4   0.50000 2
    7   4   2.00000 3
    8   4   0.50000 4
    

    List of ID / Multipliers all multiplied together selects to:

    ID  multiplier  Iteration
    1   1.80000 2
    2   1.70000 1
    3   1.00000 1
    4   0.40000 4
    

提交回复
热议问题