calculate YTD & Prev Year YTD - sql

I want to calculate YTD (1st Jan 2016 to last date of a month) & Prev year YTD (1st Jan 2015 to last date of a month) for each Client.
Below is the SQL Query that i have attempted, but here i get two rows for each Client instead of 1 as I'm using 'CASE WHEN'.
My question is how can i get the result in just one row per Client instead of one row for YTD & another row for YTD-1 for each client?
SELECT [ClientName]
, (CASE WHEN YEAR([Purchase_Date]) = YEAR(GETDATE())-1 THEN (count(Activity)) end) AS 'YTD-1'
, (CASE WHEN YEAR([Purchase_Date]) = YEAR(GETDATE()) THEN (count(Activity)) end) AS 'YTD'
FROM Purchases
WHERE MONTH([Purchase_Date]) <= MONTH(GETDATE())
GROUP BY [ClientName], YEAR([Purchase_Date])
ORDER BY 1
Kindly Help!
Thanks,
Ramesh

Remove YEAR([Purchase_Date]) from the GROUP BY part.
Also, instead of:
(CASE WHEN YEAR([Purchase_Date]) = YEAR(GETDATE())-1 THEN (count(Activity)) end) AS 'YTD-1'
use:
count(CASE WHEN YEAR([Purchase_Date]) = YEAR(GETDATE())-1 THEN Activity else NULL end) AS 'YTD-1'
And the same for 'YTD' column.

Related

How can I fetch total of Qty of Buy and Sale in month of July in single sql query

I want to find total buy and sell in single row for the specific month.
Below is the table
Month() function will help to group the month values.
SELECT
YEAR(TrDate) SaleYear,
MONTH(TrDate) SaleMonth,
SUM(CASE WHEN trType = 'B' THEN Qty END)) as TotalBuy,
SUM(CASE WHEN trType = 'S' THEN Qty END)) as TotalSale
FROM TableName
GROUP BY YEAR(TrDate), MONTH(TrDate)

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.

Adding integers to MONTH (XX) affecting logic of CASE WHEN statement, how to go around it?

Looking to get Order ID counts per month (after user signs up for a subscription service). I'm using a CASE WHEN statement where I'm taking the transaction date, then equating that to the subscription month and adding integers for each line to get Month 0, Month 1, Month 2, etc.
Ideally looking to create a concatenated year+month column to Group By so only one query is needed to get the trickle-down order value of user cohorts months 0 through 6 post enrollment. But this first draft isn't working.
Due to some Logic errors (I believe), adding integers to the month(date) function is not being read correctly, so I'm ending up with a ton of zero's after month 0.
I have checked that there indeed is rows that aren't being pulled, when I set the month (date) condition = to a certain interger ie :
count(distinct case when month(transaction_date) = 2 then order_id end) as month_1
then the code works, so this must be due to logic with adding integers to months.
select
count(user_uuid),
count(distinct case when month(transaction_date) = month (first_subscription_date) then order_id end) as month_0,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 1) then order_id end) as month_1,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 2) then order_id end) as month_2,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 3) then order_id end) as month_3,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 4) then order_id end) as month_4,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 5) then order_id end) as month_5,
count(distinct case when month(transaction_date) = (month (first_subscription_date) + 6) then order_id end) as month_6
from sandbox.select_hbw_orders
where first_subscription_date between '2018-12-01' and '2018-12-31'
and pre_or_post_subscription = 'post'
Current results:
Count(user_uuid) month_0 month_1 month_2 month_3 month_4 month_5
34,899 11,894 0 0 0 0 0
Expected results:
Count(user_uuid) month_0 month_1 month_2 month_3 month_4 month_5
34,89 11,894 4,009 3,274 3,462 3,107 3,406
What's wrong with my logic? I'm certainly able to use filters to limit the subscription month/year, but i'm going to pull about 12 months worth of data, so I want to keep things efficient with a case when statement.

SQL query overlapping time undercounting

I am writing a query that counts how many people were 18 months active on a certain day of each year.
The problem I'm having is that between the years there is an overlap in time period which causes the later years to be undercounted because they are classified as the previous year.
For example, '2017-03-06' could be considered activity for 2018 AND 2017.
Here is my query:
select case when deposit_dt between '2017-02-07' and date then '2018'
when deposit_dt between '2016-02-07' and '2017-08-07' then '2017'
when deposit_dt between '2015-02-07' and '2016-08-07' then '2016'
when deposit_dt between '2014-02-07' and '2015-08-07' then '2015'
when deposit_dt between '2013-02-07' and '2014-08-07' then '2014'
end as yr, count(unique(op_id))
from activity_table
where deposit_dt between '2013-02-07' and date
group by deposit_dt
Any advice on how to get around this issue (other than running a new query for each year)?
My feeling is that you really want something along the lines of the following:
select
count(case when deposit_dt between '2017-02-07' and date then 1 end) as 2018,
count(case when deposit_dt between '2016-02-07' and '2017-08-07' then 1 end) as 2017,
count(case when deposit_dt between '2015-02-07' and '2016-08-07' then 1 end) as 2016,
count(case when deposit_dt between '2014-02-07' and '2015-08-07' then 1 end) as 2015,
count(case when deposit_dt between '2013-02-07' and '2014-08-07' then 1 end) as 2014
from activity_table
where deposit_dt between '2013-02-07' and date;
Note that it doesn't make sense to group by deposit_dt, since this is the column which is being used to aggregate.
This assumes that you don't have logic beyond this to take the potentially overlapping dates into account. If you can provide logic for how to resolve a date which matches more than one range, then the above query can be updated.
I think this might be what you want.
select count(distinct [2018Users]) as [2018], count(distinct [2017Users]) as [2017],count(distinct [2016Users]) as [2016]
from(
select case when deposit_dt between '2017-02-07' and date then op_id end as [2018Users],
case when deposit_dt between '2016-02-07' and '2017-08-07' then op_id end as [2017Users],
case when deposit_dt between '2015-02-07' and '2016-08-07' then op_id end as [2016Users]
from activity_table
) c

SQL sum with a condition

I have a query that need to have a sum up value, but in one of my table's column, there's an increment and decrements value.
For decremented value, the value of it need to be as negative even it is stored as positive value in the table.
While for incremented value, it remains as positive.
My query look like this:
SELECT
SUM(
CASE WHEN ACTIVITY_TYPE = '0' THEN -(ACTIVITY_VALUE)
ELSE ACTIVITY_VALUE
END
) AS NEW_ACTIVITY_VALUE
FROM V_EMPLOYEE_PAYACT
WHERE ACTIVITY_TYPE IN ('0','1')
AND EMPLOYEE_NO = '00002789'
AND ((YEAR = 2014 AND MONTH <= 4)
OR
(YEAR > 2013 AND YEAR <2014)
OR
(YEAR = 2013 AND MONTH >= 5))
GROUP BY YEAR, MONTH
It return this result:
NEW_ACTIVITY_VALUE
391.00
-600.00
I need the value to be as -209 (the total of those two number)
You are currently grouping the sum per unique combination of month and year. If you want the total sum, just drop the group by clause:
SELECT
SUM(
CASE WHEN ACTIVITY_TYPE = '0' THEN -(ACTIVITY_VALUE)
ELSE ACTIVITY_VALUE
END
) AS NEW_ACTIVITY_VALUE
FROM V_EMPLOYEE_PAYACT
WHERE ACTIVITY_TYPE IN ('0','1')
AND EMPLOYEE_NO = '00002789'
AND ((YEAR = 2014 AND MONTH <= 4)
OR
(YEAR > 2013 AND YEAR <2014)
OR
(YEAR = 2013 AND MONTH >= 5))
Try this one:
SELECT
SUM(
CASE
WHEN ACTIVITY_TYPE = '0' THEN
- (ACTIVITY_VALUE)
ELSE
ACTIVITY_VALUE
END
) AS NEW_ACTIVITY_VALUE
FROM
V_EMPLOYEE_PAYACT
WHERE
ACTIVITY_TYPE IN ('0', '1')
AND EMPLOYEE_NO = '00002789'
AND (
(YEAR = 2014 AND MONTH <= 4)
OR (YEAR > 2013 AND YEAR < 2014)
OR (YEAR = 2013 AND MONTH >= 5)
)