Group by year in sql - 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.

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 Query to get Totals By Week

I need to pull a report to get some medical data for a neurologist. The following query pulls totals and averages by month. How can I change it to pull totals and averages by week?
SELECT
[Month] = DATENAME(MONTH, DATEADD(MONTH, MONTH(HeadacheDate), -1)),
[Total] = COUNT(CASE
WHEN Severity > 0 THEN 1
END),
[Light] = COUNT(CASE
WHEN Severity > 0 AND
Severity < 4 THEN 1
END),
[Moderate] = COUNT(CASE
WHEN Severity > 3 AND
Severity < 7 THEN 1
END),
[Severe] = COUNT(CASE
WHEN Severity > 6 THEN 1
END),
[DHE or ER] = COUNT(CASE
WHEN Medication LIKE '%dhe%' THEN 1
END)
FROM HeadacheData
WHERE YEAR(HeadacheDate) = 2016
GROUP BY MONTH(HeadacheDate);
Simply use WEEK instead of MONTH in the DATENAME function and also group by it.
Also a much more readable format of the query would be something like...
SELECT
[Week] = DATENAME(WEEK, DATEADD(MONTH, MONTH(HeadacheDate), -1))
,[Total] = COUNT(CASE WHEN Severity > 0 THEN 1 END)
,[Light] = COUNT(CASE WHEN Severity > 0 AND Severity < 4 THEN 1 END)
,[Moderate] = COUNT(CASE WHEN Severity > 3 AND Severity < 7 THEN 1 END)
,[Severe] = COUNT(CASE WHEN Severity > 6 THEN 1 END)
,[DHE or ER] = COUNT(CASE WHEN Medication LIKE '%dhe%' THEN 1 END)
FROM HeadacheData
WHERE YEAR(HeadacheDate) = 2016
GROUP BY DATENAME(WEEK, DATEADD(MONTH, MONTH(HeadacheDate), -1));

SQL count and group by date and type

I have a quality system table. There are 2 types of quality points NCR and RMA.
RMA is external and NCR is internal. We log transactions to the table either as a NCR or a RMA. I would like to have a query that will count all of the RMA's and all of the NCR's then group them by monthly count. For example:
MONTH RMA NCR
JANUARY 10 54
FEBRUARY 48 22
MARCH 25 55
If the value is zero for the month or the month has not yet come up, I don't want to see it on the report.
the table. this is what I have.
SELECT MONTH(QualityControl.CreateDate) MONTH, COUNT(*) AS 'NCR'
FROM QualityControl
WHERE YEAR(QualityControl.CreateDate)=2015
and
QualityControl.NCR is not null
GROUP BY MONTH(QualityControl.CreateDate)
This only gives me the month number (1=January) and the NCR count for that month.
Then I tried the following:
SELECT
SUM(CASE datepart(month,CreateDate) WHEN 1 THEN 1 ELSE 0 END) AS 'January',
SUM(CASE datepart(month,CreateDate) WHEN 2 THEN 1 ELSE 0 END) AS 'February',
SUM(CASE datepart(month,CreateDate) WHEN 3 THEN 1 ELSE 0 END) AS 'March',
SUM(CASE datepart(month,CreateDate) WHEN 4 THEN 1 ELSE 0 END) AS 'April',
SUM(CASE datepart(month,CreateDate) WHEN 5 THEN 1 ELSE 0 END) AS 'May',
SUM(CASE datepart(month,CreateDate) WHEN 6 THEN 1 ELSE 0 END) AS 'June',
SUM(CASE datepart(month,CreateDate) WHEN 7 THEN 1 ELSE 0 END) AS 'July',
SUM(CASE datepart(month,CreateDate) WHEN 8 THEN 1 ELSE 0 END) AS 'August',
SUM(CASE datepart(month,CreateDate) WHEN 9 THEN 1 ELSE 0 END) AS 'September',
SUM(CASE datepart(month,CreateDate) WHEN 10 THEN 1 ELSE 0 END) AS 'October',
SUM(CASE datepart(month,CreateDate) WHEN 11 THEN 1 ELSE 0 END) AS 'November',
SUM(CASE datepart(month,CreateDate) WHEN 12 THEN 1 ELSE 0 END) AS 'December',
SUM(CASE datepart(year,CreateDate) WHEN 2015 THEN 1 ELSE 0 END) AS 'TOTAL'
FROM
QualityControl
WHERE
CreateDate BETWEEN '2015/01/01' AND '2015/12/30'
And it gave me the count for NCR and RMA
Let's go with your first attempt, which is one row per value. You want to count the valid "NCR" and "RMA" values. You can use a COUNT() like this:
SELECT MONTH(qc.CreateDate) as MON, COUNT(NCR) as NCR, COUNT(RMA) as RMA
FROM QualityControl qc
WHERE CreateDate >= '2015-01-01' AND CreateDate < '2016-01-01'
GROUP BY MONTH(qc.CreateDate)
ORDER BY MON;
With a column (or other expression), COUNT() counts the number of non-NULL values. That seems to be exactly what you want.
If you wanted the SUM() of the values, then you would use SUM() instead of COUNT().
Note about the dates:
The version using comparisons is better than the one using YEAR(), because it can make use of indexes.
I changed the BETWEEN to >= and <. This version works correctly, if your date/time column has a time component. It also works for dates.
December has 31 days.
in sql server you can do all of these :
SELECT
CASE datepart(month,getdate()) WHEN 1 THEN 1 ELSE 0 END AS January,
CASE datepart(month,getdate()) WHEN 2 THEN 1 ELSE 0 END AS "February",
CASE datepart(month,getdate()) WHEN 3 THEN 1 ELSE 0 END AS [March]
the best method would be
SELECT datename(month, getdate())

SQL -- Show results only when count's higher than xx

So far I have this written:
SELECT
Query,
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2013-01-01' THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN SearchDate >= '2013-01-01' and SearchDate < '2014-01-01' THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
It looks at the query (search) terms in the table and counts how many times each appears in the given date range (in this case, this year and last).
In the results, I want to only show those that appear 100 times or more. Right now it's showing all.
Query Year2012 Year2013
beavers 90 87
hair 4 14
If the best method of doing this doesn't involve CASE WHEN, please let me know! Beginner here.
Use an additional having clause
SELECT
Query,
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2013-01-01' THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN SearchDate >= '2013-01-01' and SearchDate < '2014-01-01' THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
having
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2014-01-01'
THEN 1
ELSE 0
END) >= 100
I think this is a little clearer and easier to maintain:
SELECT
Query,
SUM(CASE WHEN year(SearchDate) = 2012 THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN year(SearchDate) = 2013 THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
having
SUM(CASE WHEN year(SearchDate) in (2012, 2013) THEN 1 ELSE 0 END)
>= 100