MISNole
MISNole

Reputation: 1062

Group By - Using Absolute Values

I'm trying to display an accounting report where I show total transactions, voids, the transaction fee, and a total amount for each transaction type.

TransactionType  Amount  TransactionCount   TotalAmount
AgentCredit      -$1.00   49                 -$49.00
MailFee          -$1.25   11                 -$13.75
MailFee           $1.25   531                 $663.75
HardCardFee      -$5.00   7                 -$35.00
HardCardFee       $5.00   239                $1,195.00
QuotaHuntFee     -$2.00   1                 -$2.00
QuotaHuntFee      $2.00   202                $404.00

But what I want to display would look like the following:

TransactionType Amount  TransactionCount TotalAmount    TotalTrans Voids
AgentCredit    -$1.00    49               -$49.00         49         0
MailFee         $1.25    520               $650.00        531        11
HardCardFee     $5.00    232               $1,160.00      239        7
QuotaHuntFee    $2.00    201               $402.00        202        1

Would it be possible to group the transaction types using the absolute value of the Amount and calculate the grand total along with the transaction count & void counts?

This is on SQL Server 2014.

Thanks,

Upvotes: 0

Views: 532

Answers (2)

paparazzo
paparazzo

Reputation: 45096

I think this does it

declare @T table (nm varchar(20), prc smallmoney, amt int);
insert into @T values  
       ('AgentCredit', -1.00, 49)  
     , ('MailFee', -1.25, 11)
     , ('MailFee', 1.25, 531)
     , ('HardCardFee', -5.00, 7)
     , ('HardCardFee', 5.00, 239)
     , ('QuotaHuntFee', -2.00, 1)
     , ('QuotaHuntFee', 2.00, 202);
with cte as 
(
select t.*, (t.prc * t.amt) as net 
     , count(*) over (partition by t.nm, abs(t.prc)) as cnt
     , row_number() over (partition by t.nm, abs(t.prc) order by t.prc) as rn
     , lag(t.prc) over (partition by t.nm, abs(t.prc) order by t.prc) as prPrc  
     , lag(t.amt) over (partition by t.nm, abs(t.prc) order by t.prc) as prAmt
     , case when lag(t.prc) over (partition by t.nm, abs(t.prc) order by t.prc) <  0 then t.amt - lag(t.amt) over (partition by t.nm, abs(t.prc) order by t.prc) 
            else t.amt 
       end as bal
from @T t 
)
select *, ISNULL(t.prAmt, 0) as void
     , bal*prc as nnet
from cte t 
where t.cnt = 1 
   or t.rn = 2
order by t.nm, t.prc;

Upvotes: 1

BJones
BJones

Reputation: 2460

There's a bit of confusion around your results with the data you've provided. HardCardFee has 7 and 23 in the sample you provided, but you want to return 232 for the total?.. MailFee also has some inconsistent math. Also, your 'Voids' returns 0 for the first row; however, it seems as if there are 49?

Perhaps this query could get you started down the right path:

DECLARE @Table TABLE (TransactionType varchar(20), Amount decimal(10,2), TransactionCount int, TotalAmount decimal(10,2))
INSERT @Table
VALUES  ('AgentCredit'  ,-$1.00  ,49   ,-$49.00  ),
        ('MailFee'      ,-$1.25  ,11   ,-$13.75  ),
        ('MailFee'      ,$1.25   ,531  ,$663.75  ),
        ('HardCardFee'  ,-$5.00  ,7    ,-$35.00  ),
        ('HardCardFee'  ,$5.00   ,23   ,$1195.00 ),
        ('QuotaHuntFee' ,-$2.00  ,1    ,-$2.00   ),
        ('QuotaHuntFee' ,$2.00   ,202  ,$404.00  )

;WITH c AS (
SELECT TransactionType, Amount, TransactionCount, TotalAmount,
CASE WHEN t.Amount + ABS(t.Amount) = 0 THEN '-' ELSE '' END + 
CAST(t.TransactionCount AS VARCHAR(10)) AS TCount
FROM @Table t
)

SELECT t.TransactionType
      ,MAX(t.Amount) AS Amount
      ,SUM(CAST(t.TCount AS INT)) AS TransactionCount
      ,SUM(t.TotalAmount) AS TotalAmount
      ,SUM(ABS(t.TransactionCount)) AS TotalTrans
      ,ABS(MIN(t.TCount)) AS Voids
FROM c t
GROUP BY TransactionType

Again, not sure about some of the values provided.

Upvotes: 1

Related Questions