Using multiple sum case lines in query - sql

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.

Related

SQL case operation

Im fairly new with sql, and been trying to solve a problem where you have a table information about orders. In this case, Im trying to use the case operation to get a monthly report on orders, so I should have a column which states the year,another one which states the month, and then I should have columns for days 1-20,21-22,23-24 and above 25. Im trying to use the case operation to get the amount of orders that happened on those days.
I tried the following query :
SELECT
DATEPART(YEAR,date) AS year,DATEPART(MONTH,date) AS month,
COUNT(CASE WHEN DATEPART(DAY,date) BETWEEN 1 AND 20 THEN order ELSE 0 END) AS D1_D20,
COUNT(CASE WHEN DATEPART(DAY,date) BETWEEN 21 AND 22 THEN order ELSE 0 END) AS D21_D22,
COUNT(CASE WHEN DATEPART(DAY,date) BETWEEN 23 AND 24 THEN order ELSE 0 END) AS D23_D24,
COUNT(CASE WHEN DATEPART(DAY,date) > 25 THEN order ELSE 0 END) AS D25_END
FROM ORDERS
GROUP BY DATEPART(YEAR,date),DATEPART(MONTH,date)
Obviously the problem with that query is that, now I just get the total number of orders for each of the days, I know I should count the orders, but dont know the syntax. Help would be greatly appreciated!
Use SUM():
SELECT
DATEPART(YEAR, date) AS year, DATEPART(MONTH, date) AS month,
SUM(CASE WHEN DATEPART(DAY,date) BETWEEN 1 AND 20 THEN 1 ELSE 0 END) AS D1_D20,
SUM(CASE WHEN DATEPART(DAY,date) BETWEEN 21 AND 22 THEN 1 ELSE 0 END) AS D21_D22,
SUM(CASE WHEN DATEPART(DAY,date) BETWEEN 23 AND 24 THEN 1 ELSE 0 END) AS D23_D24,
SUM(CASE WHEN DATEPART(DAY,date) > 25 THEN 1 ELSE 0 END) AS D25_END
FROM ORDERS
GROUP BY DATEPART(YEAR, date), DATEPART(MONTH, date);
I would recommend using the functions DAY(), YEAR(), and MONTH() because they are simpler to type.
By the way, you can use COUNT() if you remove the ELSE clause. Your particular problem is that COUNT(0) = COUNT(1) because COUNT() counts non-NULL values. I prefer SUM() because it is more intuitive in this respect.

91/5000 How to show dates between a range and show the number of records in that range using SQLServer

I'm trying to generate a report and it must look like this:
My inicial data is 2019/08/01 and my final data is Today.
I have to show every date between this two dates, and then the amount of records. If there is no record, it must show zero.
So I tried:
SELECT M2.[Date], COUNT(1) AS 'qtd'
FROM [RM].[Mov] AS [m2]
WHERE [m2].[TipMovId] = 1
AND ([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE())
GROUP BY [m2].[DataPosse]
SELECT m2.[Date], COUNT(1) AS 'qtd2'
FROM [RM].[Mov] AS [m2]
WHERE [m2].[TipMovId] = 4
AND ([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE())
GROUP BY [m2].[DataExercicio]
And SQL returns me something like this:
How can I join the results and show all the dates in my period??
You can do something like this
SELECT M2.[Date],
sum(case when [m2].[TipMovId] = 1 then 1 else 0 end) AS 'qtd'
sum(case when [m2].[TipMovId] = 2 then 1 else 0 end) AS 'qtd2'
sum(case when [m2].[TipMovId] = 3 then 1 else 0 end) AS 'qtd3'
sum(case when [m2].[TipMovId] = 4 then 1 else 0 end) AS 'qtd4'
FROM [RM].[Mov] AS [m2]
WHERE
([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE()) GROUP BY [m2].[Date]

How to handle aggregate function in Case statements when it involves date columns

I'm calculating invoiceDate vs currentDate then sum Value/Amount column grouping by Customer but its returning "invoiceDate is not contained in either an aggregate function or the GROUP BY clause"
select Customer
,case
when datediff(dd,InvoiceDate,getdate()) <=30 then sum(InvoiceBal1)
else 0
end as [Current]
,case
when datediff(dd,InvoiceDate,getdate()) between 31 and 60 then sum(InvoiceBal1)
else 0
end as [30 Days]
from CusInvoice
group by Customer
You want conditional aggregation:
select Customer
sum(case when datediff(day, InvoiceDate, getdate()) <= 30
then InvoiceBal1 else 0
end) as balance_current
sum(case when datediff(day, InvoiceDate, getdate()) between 31 and 60
then InvoiceBal1 else 0
end) as balance_30days
from CusInvoice
group by Customer

How do I properly group by case using a CTE? I am getting an incomplete result

below is my SQL query, where I am trying to create a stacked bar chart where different attribute values are grouped by date ranges based off the creation date. Despite my dataset having many values for each combination of attribute and date values, my query only returns a single row, with the range '46-90' broken out by attribute number.
I have looked at some related articles to this query type and I can't find what I am missing (I'm guessing this is one of those times where I've been looking at this too long and a minor little detail is escaping me). Any insight would be greatly appreciated :)
With CTE As(
SELECT obj_createDate, obj_att,
CASE when DATEDIFF(dd, obj_createdate, getDate()) <= 45 then '<45'
when DATEDIFF(dd, obj_createdate, getDate()) > 45
AND DATEDIFF(dd, obj_createdate, getDate()) <= 90 then '46-90'
when DATEDIFF(dd, obj_createdate, getDate()) > 90 then '>90'
end AS DateRange
FROM DEMO_OBJECT
WHERE DEMO_OBJECT.obj_ot_id = 24
AND DEMO_OBJECT.obj_resolveddate IS NULL
GROUP BY obj_att, obj_createDate
)
SELECT
DateRange,
COUNT(*) Total,
sum(case when obj_att = '1' then 1 else 0 end) '1',
sum(case when obj_att = '2' then 1 else 0 end) '2',
sum(case when obj_att = '3' then 1 else 0 end) '3',
sum(case when obj_att = '4' then 1 else 0 end) '4',
sum(case when obj_att = '5' then 1 else 0 end) '5'
FROM CTE
GROUP BY DateRange;

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