Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
545 views
in Technique[技术] by (71.8m points)

tsql - SQL Server Query - groupwise multiplication

If we have a table like this:

Grp       Value

Grp1          2
Grp1          5
Grp1          3
Grp2          3
Grp2         -5
Grp2         -2
Grp3          4
Grp3          0
Grp3          1
Grp4         -2
Grp4         -4
Grp5          7
Grp5       NULL
Grp6       NULL
Grp6       NULL
Grp7         -1
Grp7        10

How can we group/multiply to get this?

GrpID     Value

Grp1       30
Grp2       30
Grp3        0
Grp4        8
Grp5        7
Grp6     NULL
Grp7      -10
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Multiplying row values is the same as adding logarithms of row values

The trick is dealing with zeros and nulls.

Ok, checked now

DECLARE @foo TABLE (GrpID varchar(10), Value float)

INSERt @foo (GrpID, Value)
SELECT 'Grp1',          2
UNION ALL SELECT 'Grp1',          5
UNION ALL SELECT 'Grp1',          3
UNION ALL SELECT 'Grp2',          3
UNION ALL SELECT 'Grp2',         -5
UNION ALL SELECT 'Grp2',         -2
UNION ALL SELECT 'Grp3',          4
UNION ALL SELECT 'Grp3',          0
UNION ALL SELECT 'Grp3',          1
UNION ALL SELECT 'Grp4',         -2
UNION ALL SELECT 'Grp4',         -4
UNION ALL SELECT 'Grp5',          7
UNION ALL SELECT 'Grp5',       NULL
UNION ALL SELECT 'Grp6',       NULL
UNION ALL SELECT 'Grp6',       NULL
UNION ALL SELECT 'Grp7',         -1
UNION ALL SELECT 'Grp7',        10 

SELECT
    GrpID,
    CASE
       WHEN MinVal = 0 THEN 0
       WHEN Neg % 2 = 1 THEN -1 * EXP(ABSMult)
       ELSE EXP(ABSMult)
    END
FROM
    (
    SELECT
       GrpID, 
       --log of +ve row values
       SUM(LOG(ABS(NULLIF(Value, 0)))) AS ABSMult,
       --count of -ve values. Even = +ve result.
       SUM(SIGN(CASE WHEN Value < 0 THEN 1 ELSE 0 END)) AS Neg,
       --anything * zero = zero
       MIN(ABS(Value)) AS MinVal
    FROM
       @foo
    GROUP BY
       GrpID
    ) foo

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...