I found below query to calculate running balance.
SELECT intId, varName, decAmt, charCrDr,
SUM(CASE WHEN charCrDr = 'c' THEN
decAmt
ELSE
decAmt * -1
END )
OVER (PARTITION BY varName ORDER BY intId) As decTotal
FROM #Temp;
I would like to know what it means by else condition
This is a crude way of doing the SUM OR DIFFERENCE operation:
Here what you are trying to do is to find the difference for decAmt like below:
decAmt(where charCrDr = 'c') - decAmt
decAmt * -1 multiplies the value of decAmt by -1 so that if it is positive it becomes negative number if it is negative it becomes positive number
Actually it's about the Credit(Cr) and Debit(Dr). The running balance is:
sum of Credits - (sum of Debits)
So the decAmt for debit records (in the ELSE part, that is WHEN charCrDr != 'c') are multiplied by -1 to maintain the above formula.
Good Luck.
Related
I'm writing a query to calculate how much more the average customer has transacted and spent since signing up with my company. However, it returns the error message "Overflow occurred during numeric data type conversion".
The problem is definitely this bit, as when I comment it out the query runs successfully:
SUM(SALES_GROWTH_PERCENT)
Google tells me it's likely that I'm trying to fit a number with too many decimal places into a field that's too short for it. However, I've tried changing how many decimal places the case statements are using with no luck.
Edit: for context, here are the details of the fields being used, from syscat.columns:
This is the query in question. Can anyone see where I'm going wrong please? Any advice would be appreciated!
SELECT SUM(TRANS_GROWTH_PERCENT)/COUNT(CUSTOMER_ID) AS AVG_TRANS_GROWTH_PERCENT,
SUM(SALES_GROWTH_PERCENT)/COUNT(CUSTOMER_ID) AS AVG_SALES_GROWTH_PERCENT
FROM
(
SELECT CUSTOMER_ID,
CASE WHEN POST_SIGNUP_TRANS <=0
THEN 0
WHEN POST_SIGNUP_TRANS >0
THEN CAST((CAST(POST_SIGNUP_TRANS AS DECIMAL (10,5)) - CAST(PRE_SIGNUP_TRANS AS DECIMAL (10,5))) / CAST(PRE_SIGNUP_TRANS AS DECIMAL (10,5)) * 100 AS DECIMAL (10,1))
ELSE NULL
END AS TRANS_GROWTH_PERCENT,
CASE WHEN POST_SIGNUP_SALES <=0
THEN 0
WHEN POST_SIGNUP_SALES >0
THEN CAST((CAST(POST_SIGNUP_SALES AS DECIMAL (10,5)) - CAST(PRE_SIGNUP_SALES AS DECIMAL (10,5))) / CAST(PRE_SIGNUP_SALES AS DECIMAL (10,5)) * 100 AS DECIMAL (10,1))
ELSE NULL
END AS SALES_GROWTH_PERCENT
FROM
(
SELECT CUSTOMER_ID,
SUM(PRE_SIGNUP_TRANS) AS PRE_SIGNUP_TRANS, SUM(PRE_SIGNUP_SALES) AS PRE_SIGNUP_SALES,
SUM(POST_SIGNUP_TRANS) AS POST_SIGNUP_TRANS, SUM(POST_SIGNUP_SALES) AS POST_SIGNUP_SALES
FROM
(
SELECT CUSTOMER_ID,
CASE WHEN TRANSACTION_DATE >= ANALYSIS_START_DATE THEN 1 ELSE 0 END AS ANALYSIS_FLAG,
CASE WHEN TRANSACTION_DATE < SIGNUP_DATE THEN 1 ELSE 0 END AS PRE_SIGNUP_TRANS,
CASE WHEN TRANSACTION_DATE < SIGNUP_DATE THEN SALES ELSE 0 END AS PRE_SIGNUP_SALES,
CASE WHEN TRANSACTION_DATE >= SIGNUP_DATE THEN 1 ELSE 0 END AS POST_SIGNUP_TRANS,
CASE WHEN TRANSACTION_DATE >= SIGNUP_DATE THEN SALES ELSE 0 END AS POST_SIGNUP_SALES
FROM TRANSACTIONS_TABLE
)
WHERE ANALYSIS_FLAG = 1
GROUP BY CUSTOMER_ID
)
WHERE PRE_SIGNUP_TRANS >0
AND PRE_SIGNUP_SALES >0
)
;
I had to change my old query to a new query to get the correct results. My old query used to return a null in the denominator, so I didn't have to worry about divide by zero, the new query returns divide my zero for 'M' (R_NTWK_CHNNL), but for 'S' or R, i don't have a zero denominator. What can I do to get a null denominator in query 2? The table definition didn't change and wondering why now I don't get a null denominator when 'M' has nothing in it. Please also, how would I add nullif to the query 2? Thank you very much.
Old query
select SUM(CASE WHEN (GNRC_CD in ('O') and R_NTWK_CHNNL = 'M') then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) / sUM(CLMS) from #Clms_SMRY where SRVC_DT between #CurrentBeginDate and #CurrentEndDate)
New query
select SUM(CASE WHEN (GNRC_CD in ('O') ) and R_NTWK_CHNNL = 'M' then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) / cast(SUM(CASE WHEN GNRC_CD in ('O') and R_NTWK_CHNNL = 'M' then (CLMS) end ) as float) from #Clms_Smry where SRVC_DT between #CurrentBeginDate and #CurrentEndDate),
Use NULLIF():
select (SUM(CASE WHEN (GNRC_CD in ('O') and R_NTWK_CHNNL = 'M') then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) /
NULLIF(SUM(CLMS), 0)
)
from #Clms_SMRY
where SRVC_DT between #CurrentBeginDate and #CurrentEndDate)
I have the following query which returns a total dollar amount.
select sum(cast(dollars as dec)) from financials
This includes positive and negative values.
I would like 2 separate things:
How can I just query the positive dollar amounts? ie. I have 3 records, 10 , -5 , 10. result would be 20.
I want an absolute value as a sum. ie. I have 3 records, 10, -5, 10. the result would be 25.
thanks.
FOR 1) Use conditional SUM()
SELECT SUM( CASE WHEN dollars > 0 then dollars ELSE 0 END) as positive_sum,
SUM( CASE WHEN dollars < 0 then dollars ELSE 0 END) as negative_sum
FROM financials
FOR 2) use ABS()
SELECT SUM( ABS( dollars ) )
FROM financials
Please try below queries. Thanks.
1) select sum(cast(dollars as dec))
from financials
where dollars > 0;
2) select sum(cast(abs(dollars) as dec))
from financials;
You have two queries.solutions are as follows
1.
select sum(dollars) from financials
2.
select sum((case when dollars>0 then dollars end))+sum((case when dollars<0 then -1*dollars end)) from financials
I have this code and I'm trying to compare [Dis] to [Estimator] which is a variable I am adding:
SELECT
[Id],
[Sym],
[Month],
[Dis],
Estimator = 4/count(Id) over (partition by Sym, Month)
FROM
[RegularPayResultsYearly]
Again, I'm trying to compare Dis to Estimator.
For example, the count(Id) over (partition by Sym, [Month]) is 12091 observations.
The problem : while the Dis column is a float type (example values :
8.2944916060179E-06, 9.07691249104339E-05) it seems that the
4/count(Id) over (partition by Sym, [Month]) as cnt
which is 3.308245802663138e-4 cannot go further than zero and it showing me
Estimator = 0.
Any way to change that?
Thanks.
Unfortunately, you cannot compare floating point times using equality -- and be consistently accurate. You can have two solutions. One is to take the absolute value of the difference and call it 0 if it is less than some (arbitrary) threshold:
SELECT . . .,
(CASE WHEN ABS(Dis) - 4/count(Id) over (partition by Sym, Month)) < 0.001
THEN 'EQUAL'
ELSE 'NOTEQUAL'
END)
FROM RegularPayResultsYearly
The second is to use decimal/numeric rather than float:
SELECT . . .,
(CASE WHEN CAST(Dis, DECIMAL(10, 3)) =
CAST(4.0/count(Id) over (partition by Sym, Month) AS DCIMAL(10, 3) = 0
THEN 'EQUAL'
ELSE 'NOTEQUAL'
END)
FROM RegularPayResultsYearly
Do note that the expression 4/COUNT(ID) OVER (PARTITiON BY Sym, Month) is going to return an integer (and probably 0 at that). SQL Server does integer division when both operands are integers.
In the below code, IN ELSE, what if I dont want to pass 'NOTEQUAL' and pass a NULL Value of Float
SELECT . . .,
(CASE WHEN CAST(Dis, DECIMAL(10, 3)) =
CAST(4.0/count(Id) over (partition by Sym, Month) AS DCIMAL(10, 3) = 0
THEN 'EQUAL'
ELSE 'NOTEQUAL'
END)
FROM RegularPayResultsYearly
I have some fields in the table, need to average those fields.
Then I run this syntax, because I don't want to calculate 0 (zero) value.
SELECT myDate, AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01'
On my syntax, the average calculation means.. Make zero value to null.
My question is, How if all values are zero...?
Thank you.
Then you get NULL.
If you want zero instead, use COALESCE:
COALESCE( AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) , 0)
Average will not use nullvalues to calculate an average value
IsNull or Coalesce can be used to change null values to different values.
This script will change 0 to null and take the average value:
SELECT IsNull(AVG(NullIf(val,0)), 0)
FROM
(Values(5),(7),(0)) tbl(val)
Since 0 is excluded the result is 6
You could also do this:
SELECT myDate, COALESCE(AVG(myField1), 0) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01' and myField1 <> 0