I'm trying to get total number of applications made for current day (Monday) to (Last Monday) , and Tuesday to Last week Tuesday and so on. Also, I would like to get applications made for this Month (Month to date ). Please help
I'm using SQL Server 2008 R2
Category Date Day Applications
CASS 16/09/2019 Monday 1
CASS 16/09/2019 Monday 3
RBS 16/09/2019 Monday 1
RBS 16/09/2019 Monday 3
RBS 16/09/2019 Monday 14
RBS 16/09/2019 Monday 15
CASS 23/09/2019 Monday 2
CASS 23/09/2019 Monday 1
CASS 23/09/2019 Monday 2
CASS 23/09/2019 Monday 1
CASS 23/09/2019 Monday 8
RBS 23/09/2019 Monday 3
RBS 23/09/2019 Monday 3
Output:
23/09/2019
CASS: 14
Previous week: 14-4=10
RBS: 6
Previous week: 6-33= -27
Month to date(Total aplications till date): 57
Using LEAD() function you could achieve what you looking for, have a look at following example, you may want adjust PARTITION BY clause and sub-query as per your requirements:
Query Result..
SELECT T.*,
LEAD (AppCount) OVER (PARTITION BY cDay ORDER BY weekNum) as PrevAppCount,
T.AppCount - LEAD (AppCount) OVER (PARTITION BY cDay ORDER BY weekNum)
FROM (
select Category,
datepart(week,cDate) as weekNum,
cDay,
sum (AppCount) as AppCount
from MyTable
Group by Category, Datepart(week,cDate),cDay
) AS T
You can write query like this:
;with cte as (
select *, rown = ROW_NUMBER() over(partition by category order by [Date]) from (
select category, [Date], sum(applications) appcnt from #table
group by category, [Date]
) t
)
Select case when nextweek.Category is null then curweek.Category else
curweek.Category + ' Previous week' end ,
case when nextweek.Category is not null then nextweek.appcnt - curweek.appcnt else curweek.appcnt end
from cte curweek
left join cte nextweek on curweek.rown = nextweek.rown -1
and curweek.Category = nextweek.Category
union all
select 'Month to date', sum(applications) from #table
code:
https://rextester.com/ABI84558
I have Subscriptions that can last anywhere (as far as my output should be concerned) from 1 to 4 fiscal quarters (could also be seen as four date ranges)
I'm using Arizona Fiscal Quarters:
Q1: Jul 1st - Sep 30th
Q2: Oct 1st - Dec 31st
Q3: Jan 1st - Mar 31st
Q4: Apr 1st - Jun 30th
What I need to figure out is how many subscriptions are active in each quarter based on the subscriptions start and end dates.
For example, using (YYYY-MM-DD), I have:
A subscription that starts on 2016-07-06 and ends on 2017-02-22 I should be able to see I have a subscription active in Q1, Q2, and Q3.
Another subscription that starts on 2016-10-18 and ends on 2016-10-24 would only be seen as active for Q2
Finally, a subscription that starts on 2016-09-28 but has no end date would be seen as active for Q1, Q2, Q3, and Q4 (so whatever starting quarter all the way to Q4)
Below is my current SQL Server Script, and here it is on SQL Fiddle:
WITH SubscriptionInfo AS
(
SELECT
[Subscriptions].[Customer_Id]
,[DistributorTypes].[Name] AS [Distributor Type]
,[Customers].Zip_Id
,[Subscriptions].[UnsubscribeReason_Id]
,[Subscriptions].[Id] AS [Subscription ID]
,CONVERT(DATE, [Subscriptions].[StartDate]) AS [Subscription Start Date]
,CONVERT(DATE, [Subscriptions].[EndDate]) AS [Subscription End Date]
,[PriorityLevels].PriorityLevel AS [Priority Level]
,CONVERT(DATE, [SubscriptionPriorityLevels].StartDate) AS [Priority Level Start Date]
,CONVERT(DATE, [SubscriptionPriorityLevels].EndDate) AS [Priority Level End Date]
,[FundingSources].[Name] AS [Funding Source]
,CONVERT(DATE, [SubscriptionFundingSources].StartDate) AS [SubscriptionFundingSources Start Date]
,CONVERT(DATE, [SubscriptionFundingSources].EndDate) AS [SubscriptionFundingSources End Date]
FROM [Subscriptions]
LEFT JOIN [SubscriptionPriorityLevels]
ON [SubscriptionPriorityLevels].Subscription_Id = Subscriptions.Id
LEFT JOIN [PriorityLevels]
ON [PriorityLevels].Id = SubscriptionPriorityLevels.PriorityLevel_Id
LEFT JOIN [SubscriptionFundingSources]
ON [SubscriptionFundingSources].Subscription_Id = Subscriptions.Id
LEFT JOIN [FundingSources]
ON [FundingSources].Id = [SubscriptionFundingSources].FundingSource_Id
LEFT JOIN [Customers]
ON [Customers].Id = [Subscriptions].Customer_Id
LEFT JOIN [DistributorTypes]
ON [DistributorTypes].Id = Customers.DistributorType_Id
WHERE
([Subscriptions].StartDate >= '2016-07-01') -- Dummy dates, would later be parameters
AND ([Subscriptions].EndDate <= '2017-06-30'
OR [Subscriptions].EndDate IS NULL)
AND ([PriorityLevels].PriorityLevel IN (2, 3)) -- Only care about these two levels
AND ([Customers].DistributorType_Id = 1) -- Distributor Type: Number One Distrubition
AND ([SubscriptionFundingSources].FundingSource_Id = 2) -- Funding Source: First Bank
)
SELECT
[SubscriptionInfo].Customer_Id
,[SubscriptionInfo].[Subscription ID]
,MAX([SubscriptionInfo].[Priority Level]) AS [Highest Priority Level]
,CASE -- Determine which fiscal quarter each Subscription Start Date belongs to
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (7, 8, 9) THEN 1 -- July, August, September
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (10, 11, 12) THEN 2 -- October, November, December
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (1, 2, 3) THEN 3 -- January, Feburary, March
ELSE 4 -- April, May, June
END AS [Fiscal Quarter Start Date]
,CASE -- Determine which fiscal quarter each Subscription Start Date belongs to
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (7, 8, 9) THEN 1 -- July, August, September
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (10, 11, 12) THEN 2 -- October, November, December
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (1, 2, 3) THEN 3 -- January, Feburary, March
ELSE 4 -- April, May, June
END AS [Fiscal Quarter End Date]
FROM [SubscriptionInfo]
GROUP BY
[SubscriptionInfo].Customer_Id
,[SubscriptionInfo].[Subscription ID]
,CASE -- Group Subscription Start Date's into Fiscal Quarters
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (7, 8, 9) THEN 1 -- July, August, September
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (10, 11, 12) THEN 2 -- October, November, December
WHEN MONTH([SubscriptionInfo].[Subscription Start Date]) IN (1, 2, 3) THEN 3 -- January, Feburary, March
ELSE 4 -- April, May, June
END
,CASE -- Group Subscription End Date's into Fiscal Quarters
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (7, 8, 9) THEN 1 -- July, August, September
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (10, 11, 12) THEN 2 -- October, November, December
WHEN MONTH([SubscriptionInfo].[Subscription End Date]) IN (1, 2, 3) THEN 3 -- January, Feburary, March
ELSE 4 -- April, May, June
END
ORDER BY
[SubscriptionInfo].Customer_Id
So far I'm able to identify in what fiscal quarter a subscription started and what fiscal quarter it ended.
I want to be able to count how many subscriptions were active in each quarter.
Desired Output:
| FirstQuarter | SecondQuarter | ThirdQuarter | FourthQuarter |
|--------------|---------------|--------------|---------------|
| 2 | 1 | 3 | 3 |
Once you have a table describing the quarters' start and end dates as #Sean Lange suggested, you just need to compare your subscriptions' start and end date to the quarters' start and end date and then count them up where they overlap. Basically, two ranges have some overlap if A.Start < B.End and A.End > B.Start.
Here's a complete example of the pattern.
-------------------------
-- construct the quarters table (taken from the SQL Fiddle in comments above)
DECLARE #FiscalDate Table
(
Id INT NOT NULL,
FiscalYear INT NOT NULL,
FiscalQuarter INT NOT NULL,
QuarterStartDate DATE NOT NULL,
QuarterEndDate DATE NOT NULL
PRIMARY KEY(Id)
);
INSERT INTO #FiscalDate
(Id, FiscalYear, FiscalQuarter, QuarterStartDate, QuarterEndDate)
VALUES
( 1, 2016, 1, '2016-07-01', '2016-09-30')
,(2, 2016, 2, '2016-10-01', '2016-12-31')
,(3, 2017, 3, '2017-01-01', '2017-03-31')
,(4, 2017, 4, '2017-04-01', '2017-06-30')
;
-------------------------
--Get some random test data to imitate subscriptions ranges
DECLARE #tempSet Table(a date, b date)
INSERT INTO #tempSet SELECT TOP 15
dateadd(dd, ROUND(365 * RAND(convert(varbinary, newid())), 0), '2016-07-01') as a
, dateadd(dd, ROUND(365 * RAND(convert(varbinary, newid())), 0), '2016-07-01') as b
FROM sysobjects
-------------------------
-- Fix our random data a little (start date needs to be before end date)
DECLARE #DateRanges Table(StartDate date, EndDate date)
INSERT INTO #DateRanges
SELECT a, b FROM #tempset WHERE a <= b UNION SELECT b, a FROM #tempset WHERE b < a
-------------------------
-- Show our Date ranges in a useful order for review
SELECT * FROM #DateRanges ORDER BY StartDate, EndDate
-------------------------
-- Show our by-quarter counts.
SELECT
fd.FiscalQuarter
, count(*) as ActiveSubsCount
FROM
#FiscalDate fd
JOIN
#DateRanges dr
on fd.QuarterStartDate < dr.EndDate
and fd.QuarterEndDate >= dr.StartDate
GROUP BY
fd.FiscalQuarter
-------------------------
-- and in your desired output (without your quarters table)
SELECT
COUNT(CASE WHEN '2016-07-01' < dr.EndDate AND '2016-09-30' >= dr.StartDate THEN 1 ELSE NULL END) AS FirstQuarter
, COUNT(CASE WHEN '2016-10-01' < dr.EndDate AND '2016-12-31' >= dr.StartDate THEN 1 ELSE NULL END) AS SecondQuarter
, COUNT(CASE WHEN '2017-01-01' < dr.EndDate AND '2017-03-31' >= dr.StartDate THEN 1 ELSE NULL END) AS ThirdQuarter
, COUNT(CASE WHEN '2017-04-01' < dr.EndDate AND '2017-06-30' >= dr.StartDate THEN 1 ELSE NULL END) AS FourthQuarter
FROM
#DateRanges dr
Here is a weird one for you all.
I need to determine the number of days in a Month
;WITH cteNetProfit AS
(
---- NET PROFIT
SELECT DT.CreateDate
, SUM(DT.Revenue) as Revenue
, SUM(DT.Cost) as Cost
, SUM(DT.GROSSPROFIT) AS GROSSPROFIT
FROM
(
SELECT CAST([createDTG] AS DATE) as CreateDate
, SUM(Revenue) as Revenue
, SUM(Cost) as Cost
, SUM(REVENUE - COST) AS GROSSPROFIT
FROM [dbo].[CostRevenueSpecific]
WHERE CAST([createDTG] AS DATE) > CAST(GETDATE() - 91 AS DATE)
AND CAST([createDTG] AS DATE) <= CAST(GETDATE() - 1 AS DATE)
GROUP BY createDTG
UNION ALL
SELECT CAST([CallDate] AS DATE) AS CreateDate
, SUM(Revenue) as Revenue
, SUM(Cost) as Cost
, SUM(REVENUE - COST) AS GROSSPROFIT
FROM abc.PublisherCallByDay
WHERE CAST([CallDate] AS DATE) > CAST(GETDATE() - 91 AS DATE)
AND CAST([CallDate] AS DATE) <= CAST(GETDATE() - 1 AS DATE)
GROUP BY CALLDATE
) DT
GROUP BY DT.CreateDate
)
select distinct MONTH(CREATEDATE), DateDiff(Day,CreateDate,DateAdd(month,1,CreateDate))
FROM cteNetProfit
For some reason it is returning two different results for the month of March 2016 one result is 30 and the other 31(which of course is correct) I validate that the underlying data only has 31 days worth of data for the Month of March. Since Feb is a leap year can this affect the DATEDIFF function. The remaining months return the correct #.
2 29
3 31
3 30
4 30
5 31
Thanks for the input, however, I found the solution elsewhere
select Distinct MONTH(CREATEDATE), Day(EOMONTH(CreateDate))
FROM cteNetProfit
The difference comes when you hit the 2016-03-31 date. If you run the query below for 2016-03-30 and 2016-03-31, the results of adding 1 MONTH using DATEADD, in both instances, is 2016-04-30. It returns the last day of the next month.
SELECT DATEADD(MONTH,1,'2016-03-30') , DATEADD(MONTH,1,'2016-03-31')
This syntax seemed to work (courtesy of https://raresql.com/2013/01/06/sql-server-get-number-of-days-in-month/).
SELECT DAY(DATEADD(ms,-2,DATEADD(MONTH, DATEDIFF(MONTH,0,#DATE)+1,0))) AS [Current Month]
I am trying to implement a PIVOT but I am having trouble performing basic operations in it.
Current table:
week_no username days pick_count duration
------------------------------------------------
Week 50 Beck W Wednesday 227 7978
Week 50 Beck W Friday 320 7481
Week 50 Beck W Friday 282 5718
Week 50 Cockram D Thursday 165 10478
Week 50 Cowell P Thursday 145 14403
Week 50 Cowell P Thursday 159 7450
Week 50 Cowell P Friday 217 13101
...
Expected result:
week_no username monday tuesday wednesday thursday friday saturday sunday
--------------------------------------------------------------------------
Week 50 Beck W NULL NULL 102 NULL 164 NULL NULL
Week 50 Cockram D NULL NULL NULL 56 NULL NULL NULL
Week 50 Cowell P NULL NULL NULL 50 59 NULL NULL
...
The expected result should be calculated as followed: pick_count * 3600 / duration. That is the calculation I am having problem computing. When PIVOTing like so
SELECT
*
FROM
(
SELECT
week_no,
username,
days,
pick_count,
duration
FROM
table
) AS src
PIVOT
(
SUM(pick_count) * 3600 / SUM(duration) FOR days IN (monday, tuesday, wednesday, thursday, friday, saturday, sunday)
) AS pvt
I get Incorrect syntax near '*'.
PIVOT is not very flexible.
You can just use the old style cross tab approach.
SELECT week_no,
username,
SUM(CASE WHEN days = 'monday' then pick_count end) * 3600
/ SUM(CASE WHEN days = 'monday' then duration end) as monday,
SUM(CASE WHEN days = 'tuesday' then pick_count end) * 3600
/ SUM(CASE WHEN days = 'tuesday' then duration end) as tuesday
/*TODO: Add other five days*/
FROM YourTable
GROUP BY week_no,
username
I eventually found what I was looking for. Indeed, all I needed to do was to compute the calculation in the SELECT instead of the PIVOT.
SELECT
*
FROM
(
SELECT
week_no,
username,
days,
SUM(pick_count) * 3600 / SUM(duration) AS pick_rate
FROM
table
GROUP BY
week_no,
username,
days
) AS src
PIVOT
(
MAX(pick_rate) FOR days IN (monday, tuesday, wednesday, thursday, friday, saturday, sunday)
) AS pvt
I have an "Orders" table containing column CreatedDate (datetime) on when the order took place.
Today is Feb 13, 2014.
How to get total records for the last 4 weeks for every week.
it should return something like this:
PerDate Total
2014-01-26 13 <--- sunday
2014-02-02 24 <--- sunday
2014-02-09 33 <--- sunday
2014-02-13 35 <--- this is today
13 from the first record is the total record from 2014-01-20 00:00:00 AM (monday) to 2014-01-26 12:00:00 PM (sunday)
24 from the 2nd record is the total record from 2014-01-27 00:00:00 AM (monday) to 2014-02-02 12:00:00 PM (sunday)
33 from the 3rd record is the total record from 2014-02-03 00:00:00 AM (monday) to 2014-02-09 12:00:00 PM (sunday)
35 from the 4th record is the total record from 2014-02-10 00:00:00 AM (monday) to 2014-02-13 (today)
so they are in Ascending order.
You should use DATEPART(dw,CreatedDate) function to calculate date of begin and end of the week for each CreatedDate and then just group by this field:
WITH T AS
(
SELECT
cast(floor(cast(CreatedDate as float)) as datetime)
-DATEPART(dw,CreatedDate)+1 as BeginOfweek,
cast(floor(cast(CreatedDate as float)) as datetime)
-DATEPART(dw,CreatedDate)+8 as EndOfWeek
FROM ORDERS
WHERE cast(floor(cast(CreatedDate as float)) as datetime) BETWEEN
DATEADD(WEEK,-4,GETDATE())
AND
GETDATE()
)
SELECT
BeginOfWeek,
MIN(CASE WHEN GETDATE()<EndOfWeek
THEN GETDATE()
ELSE EndOfWeek
END) as EndOfWeek,
Count(*) as OrdersCount
FROM T
Group by BeginOfWeek
SQLFiddle demo