SQL Select Count Values negative positive and zero values - sql

Select * from Table
Date Value
2013-06-24 12
2013-06-24 3
2013-06-24 -4
2013-06-24 33
2013-06-25 12
2013-06-25 -2
2013-06-25 43
2013-06-25 1
2013-06-25 -3
and now I will count all negative, positive and zero values group by Date in one SQL-Command.

SELECT
Date,
SUM(CASE WHEN Value > 0 THEN 1 ELSE 0 END) AS pos,
SUM(CASE WHEN Value < 0 THEN 1 ELSE 0 END) AS neg,
SUM(CASE WHEN Value = 0 THEN 1 ELSE 0 END) AS zero
FROM yourTable
GROUP BY Date

You could;
select
DATE,
SUM(case when value < 0 then 1 else 0 end) as NEGATIVE,
SUM(case when value > 0 then 1 else 0 end) as POSITIVE,
SUM(case when value = 0 then 1 else 0 end) as ZERO
from
T
group by date

select date, count(case when value < 0 then value end) as Negative,
count(case when value > 0 then value end) as positive
from the_table
Hope it helps!

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);

SQL two decimal

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.

How to count occurences of value inside interval in SQL?

I have the first table that shows the amount of rain in the city by day. As request, I must display the count of days in which the rain was within an interval, like the second table.
Any ideas on how to do that?
SELECT City,
sum(case when rain = 0 then 1 else 0 end) as '0',
sum(case when (rain> 0 and rain<= 1) then 1 else 0 end) as ']0-1]',
sum(case when (rain> 1 and rain<= 2) then 1 else 0 end) as ']1-2]',
sum(case when (rain> 2) then 1 else 0 end) as '>2'
FROM MeteoData
group by City;

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';

Date Diff- TSQL # months in each year between dates

Problem: Time Span between two dates. I would like to know how many months are between each date. The trick is: the number of months in each year between the two dates.
For example:
Start date = 1/1/2014
End Date = 3/1/2016
The output:
Column 1: "2014" would have a value of 12
Column 2: "2015" would have a value of 12
Column 3: "2016" would have a value of 2
This would be for a list with many dates (with different years)
EDIT: You would indeed have to have 14 year columns for a date span between 2000-2014. However, it is unlikely that more than 5 columns would need to be added.
Current train of thought
declare #datediff as int
select
#datediff=(Datediff(MONTH,[begin date], [end date]))
from [DateRange]
select
case
when #datediff <= 12 then #datediff
when #datediff <= 24 then #datediff -12
when #datediff <= 36 then #datediff -24
when #datediff <= 48 then #datediff -36
else NULL
end
from [DateRange]
Any ideas on this one?
I am very new to SQL and was only able to get the total months between the two with the following code:
select
datediff(MONTH,[begin date], [end date])
from [tableofdates]
Use below Query, you need to use your table in place of mydates table in below example. I used for maximum 10 year difference (represented by columns Y1,Y2 ... Y10).
The outer Query group by is used transpose the data to match to your requirement where you wanted month difference in column...
Inner query Q3 will provide the same results in rows with no limit to date range (actually there is limit i.e 2048 years due to master table master..spt_values which I guess you will not reach).
select
Q3.begindt,
Q3.enddt,
Q3.Diff_in_Year,
sum(Case when Q3.Year_Counter = 0 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y1,
sum(Case when Q3.Year_Counter = 1 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y2,
sum(Case when Q3.Year_Counter = 2 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y3,
sum(Case when Q3.Year_Counter = 3 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y4,
sum(Case when Q3.Year_Counter = 4 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y5,
sum(Case when Q3.Year_Counter = 5 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y6,
sum(Case when Q3.Year_Counter = 6 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y7,
sum(Case when Q3.Year_Counter = 7 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y8,
sum(Case when Q3.Year_Counter = 8 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y9,
sum(Case when Q3.Year_Counter = 9 Then datediff(mm,Q3.y_start,Q3.y_end)+1 else 0 end) Y10
From
(select
Q1.begindt,
Q1.enddt,
Q1.years Diff_in_Year,
Q2.number as Year_Counter,
(Case when Q2.number = 0 then Q1.begindt else dateadd(yy, datediff(yy,0,dateadd(yy,q2.number,q1.begindt)),0)End) AS y_Start,
(case when ((Q1.years-1) = Q2.number) then Q1.enddt else DATEADD(yy, DATEDIFF(yy,0,dateadd(yy,q2.number+1,q1.begindt) + 1), -1) End) AS y_End,
Year(Q1.begindt)+Q2.number YearInYYYY
from
(select begindt,enddt,DATEDIFF(year,begindt,enddt)+1 as years from mydates) Q1
join master..spt_values Q2 on Q2.type = 'P' and Q2.number < Q1.years
) Q3
Group by Q3.begindt,Q3.enddt,q3.Diff_in_Year
Output of the Above Query
begindt enddt YDif Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9 Y10
2010-07-02 2014-02-06 5 6 12 12 12 2 0 0 0 0 0
2011-01-01 2014-12-31 4 12 12 12 12 0 0 0 0 0 0
2012-05-22 2017-12-16 6 8 12 12 12 12 12 0 0 0 0