I have 2 database, one in Mysql and a second in SQL Server. In these 2 databases, I have a table tb_Episode, both databases have same records.
When I run this query in Mysql, it returns a result of 5.1582, whereas in SQL Server, it returns 5.
Why am I getting different results? I use this query - can anyone please help me, how can I resolve this error?
SELECT
AVG(CASE
WHEN (SN_Ep = '1' AND MonthEnd = '2017-04')
THEN SN_Visits
ELSE NULL
END) AS SNVisitsSNEps_2017_04
FROM
tb_Episode
WHERE
CustID = '27'
AND PayerType = 'Ep'
AND BranchID IN (238, 239, 240, 241)
In SQL Server the return data-type of AVG() is determined by the input data-type.
https://learn.microsoft.com/en-us/sql/t-sql/functions/avg-transact-sql
If you average a column of integers, the result will be an integer. If you want the result to be a different data-type, cast the input to be that data-type.
As an example...
AVG(
CAST(
CASE when (SN_Ep = '1' and MonthEnd='2017-04') then SN_Visits ELSE NULL END)
AS
DECIMAL(18,10)
)
)
Please try like this -
AVG(
CASE when (SN_Ep = '1' and MonthEnd='2017-04') then SN_Visits * 1. ELSE NULL END)
)
Some guidance for both databases:
else NULL is redundant.
If a value is a number, don't compare it to a string.
Then, you want to convert the integer type to a number for SQL Server. A simple way is to multiply by 1.0.
I would suggest for both:
SELECT AVG(CASE when SN_Ep = 1 and MonthEnd = '2017-04' THEN SN_Visits * 1.0 END) as SNVisitsSNEps_2017_04
FROM tb_Episode
WHERE CustID = 27 AND
PayerType = 'Ep' AND
BranchID IN (238, 239, 240, 241) ;
Related
I need to present the attached output in PIC1 as the result in PIC2. The query used for generating PIC1 output in SQLDeveloper:
select subs_nm, as_of_date, run_status, (select max (tp.pr_vl)
from ual_mng.tqueue tq, ual_mng.tparams tp, ual_mng.tstatus ts
WHERE tq.tid = tp.tid AND tq.tid = ts.tid and tq.run_id = pcm.run_id and tp.pr_nm in ('TOT_RECORD_CNT')) as RECORD_COUNT
from UAL_MNG.PCM_SUBS_RUN_DTL_VW pcm where SUBS_NM='S_TS2_AQUA_A1_RLAP_DL' and AS_OF_DATE in ('2021-09-01','2021-09-02') order by run_start_dtm desc;
Appreciate all help.
If you don't need it to be dynamic (ie. it will only be two columns and you know which two months they are) you can do
select subs_nm,
max(case when as_of_date = '2021-09-01' then RECORD_COUNT else 0 end) as SEP1,
max(case when as_of_date = '2021-09-02' then RECORD_COUNT else 0 end) as SEP2,
from (
-- Your query
)
group by subs_nm
You can work out the percentage difference using the same expressions.
nb. I would always use an explicit date format mask. This might not run on a different machine / software. So use to_date('2021-09-01', 'yyyy-mm-dd')
Posting the query, which worked in the script :
select subs_nm, SEP1, SEP2, round((((SEP1-SEP2)/SEP1)*100),2) as DIFF_PER from ( select subs_nm,
max(case when as_of_date='2021-09-01' then RECORD_COUNT else '0' end) as SEP1,
max(case when as_of_date='2021-09-02' then RECORD_COUNT else '0' end) as SEP2 from (-- *Main Query*);
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)
Reference from How to sum time using mysql
I want to SUM Field LogsFormatted.Late Every month with query :
SELECT
SUM(CASE
WHEN MONTH (LogsFormatted.DateIn) = 1
THEN SEC_TO_TIME( SUM( TIME_TO_SEC(LogsFormatted.Late)))
ELSE 0 END
) AS '1'
FROM
HrAttLogsFormatted AS LogsFormatted
But the result is
1111 - Invalid use of group function
Where is the problem with the query? resulting in an error output.. Thank you in advance
[EDIT-SOLVED] It's Solved with simply apply
Change format SUM at the beginning of the query
SEC_TO_TIME(SUM(
CASE WHEN MONTH(LogsFormatted.DateIn) = 1 THEN
TIME_TO_SEC(LogsFormatted.Late) END)
) AS '1'
You don't need to call the sum() so many times. You can also move the case condition to the WHERE clause:
SELECT SUM(TIME_TO_SEC(lf.Late))
FROM HrAttLogsFormatted lf
WHERE MONTH(lf.DateIn) = 1 ;
If you want conditional aggregation, then do:
SELECT SUM(CASE WHEN MONTH(lf.DateIn) = 1 THEN TIME_TO_SEC(lf.Late) END)
FROM HrAttLogsFormatted lf;
I'm having trouble with this piece of SQL:
SELECT
(CASE
WHEN u.password IS NULL
THEN 'GUEST'
ELSE 'CUSTOMER'
END) as STATUS,
u.date_created, u.name as UserName, u.password, u.email,
r.token as Currency,
(CASE
WHEN u.balance > 0
THEN LEFT(u.balance, LEN(u.balance) - 2) + '.' + RIGHT(u.balance, 2)
ELSE 0
END) as Balance
FROM
[user] u
INNER JOIN
[region] r ON r.currency_id = u.balance_currency
It is showing this error:
Conversion failed when converting the varchar value '24.00' to data type int.
It started happening when i added the line:
(CASE WHEN u.balance >0 THEN left(u.balance,len(u.balance)-2)+'.'+right(u.balance,2)
ELSE 0 END) as Balance
This line tries to turn u.balance, which has values like 2400, to 24.00 only when the value is greater than 0. It is a numerical(10,0) field, so i'm not sure why it's using 24.00 and considering it a varchar. Any help will be greatly appreciated! THanks!
caseexpression should return the same data types. In this case use '0' instead of numeric value 0, because you are returning a varchar in when.
CASE WHEN u.balance >0 THEN left(u.balance,len(u.balance)-2)+'.'+right(u.balance,2)
ELSE '0' END
Hmmm, storing numbers as strings is generally a bad idea. I think you can get the desired behavior by doing something like this:
(case when isnumeric(u.balance) = 0
then '0'
when cast(u.balance as float) > 0.0
then stuff(u.balance, len(u.balance - 2), 0, '.')
else '0'
end)
However, I would encourage you to reconsider storing numbers as strings.
Note: You can fix your version of the code just by using 0.0 for the constant rather than 0.
I would like to do something like this:
select sum(nvl(total_time_out, 0)),
sum(nvl((case when day_of_week = 'Mon' then total_time_out else 0 end) over (partition by person_id), 0))
from xxpay_tna_summary_v
where person_id = 7926
where the second column only returns the sum of the total time out hours for the Monday. Is this possible in Oracle SQL, and what is the correct syntax?
check this
http://sqlfiddle.com/#!4/df376/2
select sum((case when person_id = 100 then total_time_out else 0 end)) total_time,
sum(nvl((case when day_of_week = 'MON' then total_time_out else 0 end), 0)) monday_time
from xxpay_tna_summary_v
Your syntax is invalid, because sum belongs to over, but you moved the sum keyword to the beginning of the expression. Here is the corrected statement:
select nvl(sum(total_time_out), 0),
nvl(sum(case when day_of_week = 'Mon' then total_time_out else 0 end) over (partition by person_id), 0)
from xxpay_tna_summary_v
where person_id = 7926;
(I also changed places for sum and nvl in your first expression. It does the same but might be nanoseconds faster, because nvl has to be applied just once.)