sum of new columns within a query - sql

I have the below query:
SELECT distinct COUNT(Status) AS [Transactions], sending_organisation AS [Supplier],
DATENAME(mm, Date_Reported) AS Month, DATENAME(yyyy, Date_Reported) AS Year,
Sum(Case When Status = 'Defect' Then 1 Else 0 End) As Defect,
Sum(Case When Status = 'Failed' Then 1 Else 0 End) As Failed,
Sum(Case When Status = 'Success' Then 1 Else 0 End) As Success,
FROM [Tx]
where Channel_Partner = 'CAT'
and DATENAME(yyyy, Date_Reported) = '2018'
and DATENAME(mm, Date_Reported) = 'March'
GROUP BY DATENAME(mm, Date_Reported), DATENAME(yyyy, Date_Reported), sending_organisation
ORDER BY sending_organisation ASC
As you can see I have created the new columns of defect, success, failed.
I wanted to add another column within this same query in finding an aggregated sum of failed + success?
Any ideas how this could done without creating a table or doing more than one query?
thanks in advance

Just add a further column with another COUNT(<expr>):
SUM(CASE WHEN [Status] IN ('Success','Failed') THEN 1 ELSE 0 END) AS SuccessFailed
Further to the OP's comments, (on a totally unrelated matter), to return the data for the current month I would use:
AND Date_Reported >= DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()),0)
AND Date_Reportded < DATEADD(MONTH, DATEDIFF(MONTH,0,GETDATE()) + 1,0)
You should be able to alter this slighly for your own needs, if needed. Using something like DATENAME on your column isn't a good idea; it makes the query non-SARGable.

Related

Query to show all months and show values where there are data for the corresponding months

I have a query and it shows the months where there is corresponding data. However, I would like to show all of the months in the year and have the months where there are no data shown as zero.
There is my SQL Statement:
SELECT DATENAME(MONTH, hb_Disputes.OPENED) AS MonthValue,
COUNT(CASE WHEN REV_CLS = 2 THEN 1 END) AS SmallCommercialIndust,
COUNT(CASE WHEN REV_CLS <> 2 THEN 1 END) AS Residential
FROM hb_Disputes
WHERE (hb_Disputes.ASSGNTO = 'E099255') AND (YEAR(hb_Disputes.OPENED) = YEAR(GETDATE()))
GROUP BY hb_Disputes.OPENED
And this is my output:
I also have a table name MonthName that shows all of the months in a year and I know I may need to use this to accomplish what I'm trying to achieve but I'm not sure how to get there:
If you have data in the table for all months, but the where clause is filtering it out, then the simplest method is to extend the conditional aggregation:
SELECT DATENAME(MONTH, d.OPENED) AS MonthValue,
SUM(CASE WHEN d.ASSGNTO = 'E099255' AND d.REV_CLS = 2 THEN 1 ELSE 0 END) AS SmallCommercialIndust,
SUM(CASE WHEN d.ASSGNTO = 'E099255' AND d.REV_CLS <> 2 THEN 1 ELSE 0 END) AS Residential
FROM hb_Disputes d
WHERE YEAR(d.OPENED) = YEAR(GETDATE())
GROUP BY DATENAME(MONTH, d.OPENED)
ORDER BY MIN(d.OPENED);
Note: This does not fix the issue in all cases. It should just be a simple way to modify your query -- and will often work.

SQL Server query, remove date dimension

I need help in removing the date dimension from the query below. In other words make the query independent of the date / time interval
My goal is to load the table into SSAS so that i would not have to change the date every time i run reports.
the query is huge (months, quarters, years, and aggregated date CR12,PR12 ...), i just gave a short example below
I sincerly appreciate any help
drop table #tmptmp
SELECT *, (DATEDIFF(day, enrollmentsDate, ShipmentDate))
- ((DATEDIFF(WEEK, enrollmentsenttDate, InitialShipmentDate) * 2)
+(CASE WHEN DATENAME(DW, enrollmentsentDate) = 'Sunday' THEN 1 ELSE 0 END)
+(CASE WHEN DATENAME(DW, ShipmentDate) = 'Saturday' THEN 1 ELSE 0 END)
- (select count(*) from tblFactoryHolidayDates where Date >= enrollmentsentDate
and Date < InitialShipmentDate)) as countdays into #tmptmp from
#tmpTouchpointsEnrollments
where EnrollmentSentDate is not null
----------------------------
drop table #tmp
select * into #tmp
from #tmptmp
where countdays < 20
drop table #tmpMetric
Select 'GrandTotal' as Dummy,'Avg days' as Metrics,'1' as MetricOrder,
Sum(case when Year(EnrollmentReceiveddate) ='2010' then (countdays) end) *1.0/
count(case when Year(EnrollmentReceiveddate) ='2010' then (patientID) end) *1.0 as Y2010,
into #tmpMetric
from #tmp
Thank you very much

Using multiple sum case lines in query

This code does exactly what I need it to do for the desired months. Basically provides Numerator and Denominator.
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' THEN 1 ELSE 0 END) AS Total_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' THEN 1 ELSE 0 END) AS Total_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-03-01' and '2013-03-31' THEN 1 ELSE 0 END) AS Total_Mar13,
It can get pretty tedious when you have multiple months...is there a more efficient way of performing this calculation?
THanks!
You could group them by the year and month in a sub-select and then manipulate that:
SELECT DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalYear,
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalMonth,
COUNT(*) AS Total
FROM [table]
GROUP BY DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date),
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date)
and that would give you the totals by month, without having to specify the months beforehand.

'Conversion failed when converting the varchar value to int' in case if function

I have trouble running the following query.
I need to find a number of [ID]s used per each model per each day of week. I don't have trouble running similar query to sum up other metrics.
But in this case I receive a message "Conversion failed when converting the varchar value '07:2767:90:56' to data type int".
I can execute a count query for [ID] without (case if) function with no trouble.
SELECT model,
count(CASE WHEN datepart(weekday, [date]) =2 THEN (ID)else 0 END) AS [Monday]
count(CASE WHEN datepart(weekday, [date]) =3 THEN (ID)else 0 END) AS [Tuesday]
count(CASE WHEN datepart(weekday, [date]) =4 THEN (ID)else 0 END) AS [Wednesday]
count(CASE WHEN datepart(weekday, [date]) =5 THEN (ID)else 0 END) AS [Thursday]
count(CASE WHEN datepart(weekday, [date]) =6 THEN (ID)else 0 END) AS [Friday]
from clientdata
where [date] between cast ((GETDATE() -7) AS date) and cast (GETDATE()-1 AS date)
group by d.model;
Try This
SELECT model,
count(CASE WHEN datepart(weekday,[date])=2 THEN ID else 0 END) AS [Monday],
count(CASE WHEN datepart(weekday,[date])=3 THEN ID else 0 END) AS [Tuesday],
count(CASE WHEN datepart(weekday,[date])=4 THEN ID else 0 END) AS [Wednesday],
count(CASE WHEN datepart(weekday,[date])=5 THEN ID else 0 END) AS [Thursday],
count(CASE WHEN datepart(weekday,[date])=6 THEN ID else 0 END) AS [Friday]
from clientdata d
where [date] between (GETDATE() -7) and (GETDATE()-1)
group by d.model;
I'm not sure why you are getting that specific error, but I see several problems:
No commas after fields in your select (need one after Monday, Tuesday, etc.)
You are grouping by d.model where d is not a valid table alias
Your query will not return the results you are looking for. All the counts will be the same for the days. You want to use SUM, something along the lines of:
SUM(CASE WHEN datepart(weekday, [date]) =2 THEN 1 else 0 END) AS [Monday]

Having trouble with a query in SQL Server

Let's say I've got a SQL Server table that logs user activity. Let's say it has user ID, user name, activity date, and activity type columns. I want to print out a list of all user activity, with one row for each month of activity, and a column for each activity type summing up the number of times that activity occurred in that month. I'm trying to do this with the following query:
SELECT
user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120),
SUM(CASE WHEN activity_type = 'Log In' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Save Document' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Create Document' THEN 1 ELSE 0 END)
FROM UserActivity
WHERE DATE BETWEEN '11-1-2010 00:00:00' AND '12-31-2010 23:59:59'
GROUP BY user_id, user_name, CONVERT(VARCHAR(7), activity_date, 120)
The problem is, this query is essentially giving me a separate row for each activity--lots and lots of rows, no counting. I think that the problem is with the way I'm doing the dates, because if I change the query to not select the date, I get a table that looks "mostly correct."
Any thoughts?
You can't have a SUM without a GROUP BY, at least not with other non-aggregates in the SELECT. Do your GROUP BY clause properly.
SELECT
user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120),
SUM(CASE WHEN activity_type = 'Log In' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Save Document' THEN 1 ELSE 0 END),
SUM(CASE WHEN activity_type = 'Create Document' THEN 1 ELSE 0 END)
FROM UserActivity
WHERE DATE BETWEEN '11-1-2010 00:00:00' AND '12-31-2010 23:59:59'
GROUP BY user_id,
user_name,
CONVERT(VARCHAR(7), activity_date, 120)
For what it's worth, for date ranges, I prefer to use
WHERE DATE >= '20101101'
AND DATE < '20110101'
I'm sure losing a few records with a timestamp of '12-31-2010 23:59:59.997' won't matter, but it's just more logically correct to use a < next_date test. And to be pedantic, the format YYYYMMDD is the most robust regardless of regional/language/dateformat settings.