SQL two decimal - sql

How to make persen_sukses or persen_gagal only get 2 decimal ?
I try use round but get some error.
May be anyone can help me.
Here is my sql
SELECT * ,(CASE WHEN all_trx.trx_gagal = 0 THEN 100 WHEN all_trx.trx_sukses = 0 THEN 0 ELSE (CAST(all_trx.trx_sukses AS float)/CAST(all_trx.trx_total AS float)*100) END) AS persen_sukses,
(CASE WHEN all_trx.trx_sukses = 0 THEN 100 WHEN all_trx.trx_gagal = 0 THEN 0 ELSE (CAST(all_trx.trx_gagal AS float)/CAST(all_trx.trx_total AS float)*100) END) AS persen_gagal
FROM
(SELECT kode_produk AS Produk,
COUNT(CASE WHEN status = '20' THEN 1 END) AS trx_sukses,
COUNT(CASE WHEN status > '20' THEN 1 END) AS trx_gagal,
COUNT(CASE WHEN status >= '20' THEN 1 END) AS trx_total
FROM transaksi WHERE CAST(tgl_entri AS DATE) = CAST(GETDATE() AS DATE) GROUP BY kode_produk)
AS all_trx

SELECT *
,(CASE
WHEN all_trx.trx_gagal = 0 THEN 100
WHEN all_trx.trx_sukses = 0 THEN 0
--ELSE (CAST(all_trx.trx_sukses AS float)/CAST(all_trx.trx_total AS float)*100)
ELSE CAST(all_trx.trx_sukses*100.0 / all_trx.trx_total as numeric(18,2) )
END) AS persen_sukses
,(CASE
WHEN all_trx.trx_sukses = 0 THEN 100
WHEN all_trx.trx_gagal = 0 THEN 0
--ELSE (CAST(all_trx.trx_gagal AS float)/CAST(all_trx.trx_total AS float)*100)
ELSE CAST(all_trx.trx_gagal*100.0 / all_trx.trx_total as numeric(18,2) )
END) AS persen_gagal
FROM
(
SELECT
kode_produk AS Produk,
COUNT(CASE WHEN status = '20' THEN 1 END) AS trx_sukses,
COUNT(CASE WHEN status > '20' THEN 1 END) AS trx_gagal,
COUNT(CASE WHEN status >= '20' THEN 1 END) AS trx_total
FROM transaksi
WHERE CAST(tgl_entri AS DATE) = CAST(GETDATE() AS DATE)
GROUP BY kode_produk
) AS all_trx
Dear i am able to fix the issue in your query, Pleae note the only change i did is ELSE part of Case Statement. I executed the query and now returning the value upto two decimal places only. If you have to increase or decrease the digits after the decimal sign update the value of numeric(18,2) here 2 is number of digit after decimal.

Related

How to display 0 in all the columns in a table when sum returned for all the columns is 0?

Currently I am getting Blank columns But I want 0 Here as shown in the image. Click here for the Image. Below is my query and I want all the columns to display 0 when sum returned is 0.
SELECT COUNT(*) AS Inserted,
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS Pending,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS Completed,
SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) AS Failure
FROM [dbo].[ETIME_TIMECARD]
where cast(CreateDateTime as date) = CAST(GETDATE() AS DATE)
Group By cast(CreateDateTime as date)
You're getting no results because your WHERE isn't returning any results and you have a GROUP BY with nothing to group on. In truth, the GROUP BY appears to not be required.
SELECT COUNT(*) AS Inserted,
ISNULL(SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END),0) AS Pending,
ISNULL(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END),0) AS Completed,
ISNULL(SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END),0) AS Failure
FROM [dbo].[ETIME_TIMECARD]
WHERE CreateDateTime >= CAST(GETDATE() AS date)
AND CreateDateTime < CAST(DATEADD(DAY, 1, GETDATE()) AS date);
Though, personally, I would switch to a COUNT as you clearly are counting, and then you don't need to ISNULL, as a COUNT will not return NULL:
SELECT COUNT(*) AS Inserted,
COUNT(CASE status WHEN 0 THEN 1 END) AS Pending,
COUNT(CASE status WHEN 1 THEN 1 END) AS Completed,
COUNT(CASE status WHEN 2 THEN 1 END) AS Failure
FROM [dbo].[ETIME_TIMECARD]
WHERE CreateDateTime >= CAST(GETDATE() AS date)
AND CreateDateTime < CAST(DATEADD(DAY, 1, GETDATE()) AS date);

Get data of 2 different dates in 2 different columns sql

I have a sql table having columns Name, VisitingDate, StayTime
I want a query which can give me data in which in 1 column I can get data of thismonthvisit and other column I can get data of lastmonthvisit and in 3rd column I can data of summation of StayTime of particular person .
Database Table : --
Name
VisitingDate
StayTime(in minutes)
A
2021-04-20
5
A
2021-04-21
15
A
2021-03-20
10
B
2021-03-20
5
Result Wanted : --
Name
Thismonthvisit
TotalStayTimeThismonth(in minutes)
LastmonthVisit
TotalStayTimelastmonth(in minutes)
A
2
20
1
10
B
0
0
1
5
Here is what you are looking for :
select name,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(getdate(),'YYYYMM') THEN 1 ELSE 0 END) AS ThisMonthVisit,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(getdate(),'YYYYMM') THEN StayTime ELSE 0 END) AS TotalStayTimeThisMonth,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(dateadd(month, -1, getdate()),'YYYYMM') THEN 1 ELSE 0 END) AS LastMonthVisit,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(dateadd(month, -1, getdate()),'YYYYMM') THEN StayTime ELSE 0 END) AS TotalStayTimeLastMonth
from MyTable
where FORMAT(VisitingDate, 'YYYYMM') > FORMAT(dateadd(month, -2, getdate()),'YYYYMM')
group by Name
SEE DEMO HERE
You can use aggregation:
select name,
sum(case when month(visitingdate) = month(getdate())
then 1 else 0
end) as cnt_thismonth,
sum(case when month(visitingdate) = month(getdate())
then staytime else 0
end) staytime_thismonth,
sum(case when month(visitingdate) <> month(getdate())
then 1 else 0
end) as cnt_lastmonth,
sum(case when month(visitingdate) <> month(getdate())
then staytime else 0
end) staytime_lastmonth
from t
where visitingdate >= dateadd(month, -1, datefromparts(year(getdate()), month(getdate()), 1))
group by name;

SQL row in column

I have this SQL query
SELECT COUNT(*)*100/(SELECT COUNT(*) FROM tickets WHERE status = 'closed')
FROM tickets
WHERE closed_at <= due_at
UNION
SELECT COUNT(*)*100/(SELECT COUNT(*) FROM tickets WHERE status = 'closed')
FROM tickets
WHERE closed_at > due_at;
and it returns this
ROW 1 - 35
ROW 2 - 47
but I need the return like this:
1 | 2 |
35 47
I need the returns in columns, not rows.
Thanks.
Use conditional aggregation. I would recommend:
SELECT (SUM(CASE WHEN closed_at <= due_at THEN 100.0 ELSE 0 END) /
SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END)
),
(SUM(CASE WHEN closed_at > due_at THEN 100.0 ELSE 0 END) /
SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END)
)
FROM tickets ;
It seems strange that you are filtering on status = 'closed' in the denominator, but not in the numerator. If status = closed should be the filter for both, then you can simplify this to:
SELECT AVG(CASE WHEN closed_at <= due_at THEN 100.0 ELSE 0 END),
AVG(CASE WHEN closed_at > due_at THEN 100.0 ELSE 0 END)
FROM tickets
WHERE status = 'closed';

Sum case statement

The below SQL is returning 'Cannot perform an aggregate function on an expression containing an aggregate or a subquery.', can anyone help?
SELECT
sum(case when Frequency = 'Monthly' then ISNULL(SUM(Amount),0.0) else 0 end) +
sum(case when Frequency = '4 Weekly' then ISNULL(SUM(Amount),0.0) / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then ISNULL(SUM(Amount),0.0) / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then ISNULL(SUM(Amount),0.0) / 5 else 0 end)
FROM TableWHERE Id = 1
If you want conditional aggregation, you only want one sum():
SELECT sum(case when Frequency = 'Monthly' then Amount else 0 end) +
sum(case when Frequency = '4 Weekly' then Amount / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then Amount / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then Amount,0.0) / 5 else 0 end)
FROM Table
WHERE Id = 1;
I think you want to do something like
sum(case when Frequency = 'Monthly' then ISNULL(Amount,0.0) else 0 end)
SELECT
sum(case when Frequency = 'Monthly' then ISNULL(Amount,0.0) else 0 end) +
sum(case when Frequency = '4 Weekly' then ISNULL(Amount,0.0) / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then ISNULL(Amount,0.0) / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then ISNULL(Amount,0.0) / 5 else 0 end)
FROM Table
WHERE Id = 1

Group by year in sql

I am trying to group by year but was not able to do.I can get the column count but not year wise. this is what i tried.
select t_contract ,
sum(CASE t_contract when '18' then 1 else 0 end) as XL,
sum(CASE t_contract when '01' then 1 else 0 end) as VC,
sum(CASE t_contract when '75' then 1 else 0 end) as AN,
sum(CASE t_contract when '48' then 1 else 0 end) as CS
from icps.dbo.tickets
WHERE
t_date_time_issued >= DATEADD(year, -6, GETDATE())
GROUP BY contract
.. but i want to add year .. where i have t_date_time _issued column.
My another query is I have a column called t_zone_name and I want to sum all the rows where t_zone_anme like '%ICeland%' an i tried this:
sum(CASE t_zone_name like '%ICeland%' then 1 else 0 end) as ICELAND
but I get an error on statement like... thanks in advance.
LIKE
YEAR XL VC AN CS total
2010 50 50 50 50 200
2011 5 5 5 5 20
Try the below query:
SELECT t_contract, YEAR(t_date_time_issued) As Yr, SUM(CASE WHEN t_zone_name like '%ICeland%' THEN 1 ELSE 0 END) AS ICELAND
SUM(CASE t_contract when '18' then 1 else 0 end) as XL,
SUM(CASE t_contract when '01' then 1 else 0 end) as VC,
SUM(CASE t_contract when '75' then 1 else 0 end) as AN,
SUM(CASE t_contract when '48' then 1 else 0 end) as CS
FROM icps.dbo.tickets
WHERE YEAR(t_date_time_issued) >= (YEAR(GetDate()) - 6)
GROUP BY t_contract, YEAR(t_date_time_issued)
You might need change the order of t_contract and YEAR(t_date_time_issued) depending on which grouping you want to apply first.
As suggested by #ray I have replaced DATEPART(yyyy, t_date_time_issued) >= DATEPART(yyyy, DATEADD(year, -6, GETDATE())) with year(t_date_time_issued) >= (year(GetDate()) - 6)
If you want to group by year, in sql server, you might
GROUP BY DATEDIFF(year,t_date_time_issued, GETDATE())
In other DB engine, usually has method to get year part, or use substring to get year part from a time string.