pass date dynamically to a query to calculate day wise results - sql-server

I created a new topic as i am trying to divide my initial question into multiple pieces.
The initial topic can be found in the following link.
I have created a SQL Fiddle link with table and sample data.
This is the Query that i have right now.
SELECT
Order1,
COUNT(UNit.UNIT) AS Units,
SUM(CASE
WHEN (DATEDIFF(dd, INSV_DATE, '2015-01-21')) >= 31 THEN 31
WHEN (DATEDIFF(dd, INSV_DATE, '2015-01-21')) < 0 THEN 0
ELSE (DATEDIFF(dd, INSV_DATE, '2015-01-21'))
END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-01-21'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
customer
how do i loop and pass date dynamically in the Datediff for a period of one month?
I want the 31 days output calculated for day wise.
The output should be like
Date | Order1 | Unit | Day31
----------------------------------
May20 | 90909 | 5 | 128
May19 | 90909 | 4 | 124
May17 | 90909 | 2 | 62
I actually want to do something like the following.
SELECT
Order1,
COUNT(UNit.UNIT) AS Units,
SUM(CASE
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-20')) >= 31 THEN 31
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-20')) < 0 THEN 0
ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-20'))
END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-20'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
customer
SELECT
Order1,
COUNT(UNit.UNIT) AS Units,
SUM(CASE
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-19')) >= 31 THEN 31
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-19')) < 0 THEN 0
ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-19'))
END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-19'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
customer
SELECT
Order1,
COUNT(UNit.UNIT) AS Units,
SUM(CASE
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-18')) >= 31 THEN 31
WHEN (DATEDIFF(dd, INSV_DATE, '2015-05-18')) < 0 THEN 0
ELSE (DATEDIFF(dd, INSV_DATE, '2015-05-18'))
END) AS Days31
FROM UNIT
WHERE Unit.INSV_DATE < '2015-05-18'
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
GROUP BY [Order1],
customer
Running the same query for everyday with the different date.
If you can guide me in making a day wise query that will be great.

You can build the list of dates using a recursive CTE, then CROSS JOIN it against your table to get the list of days you want:
DECLARE #StartDate date = 'Jan 1, 2015'
DECLARE #EndDate date = DATEADD(DAY, 30, #StartDate)
;WITH cte AS (
SELECT #StartDate AS ReportDate
UNION ALL
SELECT DATEADD(DAY, 1, ReportDate)
FROM cte
WHERE ReportDate < #EndDate
)
SELECT Order1,COUNT(UNit.UNIT) As Units,sum(CASE
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) >= 31 THEN 31
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) < 0 THEN 0
ELSE (datediff(dd,INSV_DATE,cte.ReportDate))END) as Days31
FROM UNIT
CROSS JOIN cte
WHERE Unit.INSV_DATE < cte.ReportDate AND
UNIT.MODEL in('Toyota') AND(UNIT.Customer in('Jona' ))
group by [Order1],customer

Based on my understanding of what you want, here is my "guess":
DECLARE #startDate DATE = CAST(MONTH(GETDATE()) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(GETDATE()) AS VARCHAR) -- cast as mm/dd/yyyy
DECLARE #endDate DATE = GETDATE() -- mm/dd/yyyy
--creates a list of dates for the running month
;WITH month_dates
AS (
SELECT [Date] = DATEADD(Day, Number, #startDate)
FROM master.dbo.spt_values
WHERE Type = 'P'
AND DATEADD(day, Number, #startDate) <= #endDate
)
SELECT month_dates.[Date]
,Order1
,COUNT(UNit.UNIT) AS Units
,sum(CASE
WHEN (datediff(dd, INSV_DATE, month_dates.[Date])) >= 31
THEN 31
WHEN (datediff(dd, INSV_DATE, month_dates.[Date])) < 0
THEN 0
ELSE (datediff(dd, INSV_DATE, month_dates.[Date]))
END) AS Days31
FROM UNIT
CROSS JOIN month_dates --cross join list of dates
WHERE Unit.INSV_DATE < month_dates.[Date]
AND UNIT.MODEL IN ('Toyota')
AND (UNIT.Customer IN ('Jona'))
AND UNIT.Order1 = 'A1056729' --added this filter to test the output
GROUP BY month_dates.[Date]
,[Order1]
,customer
ORDER BY month_dates.[Date] desc

Related

How can I merge two select queries with counts of mostly identical columns but one set returns multiple rows

I have two queries that work perfectly:
DECLARE #StartDate DATETIME = '2021-11-01 00:00:00';
DECLARE #EndDate DATETIME = '2022-03-16 23:59:59';
DECLARE #SalesEstimateTransactionTypeId INT = 16;
DECLARE #SalesOrderTransactionTypeId INT = 15;
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
COUNT(TransactionId) AS TransactionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= #StartDate
AND GeneralJournal.[TransactionDate] <= #EndDate
AND MasterRecord = 1
AND TransactionTypeId = #SalesEstimateTransactionTypeId
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
COUNT(DISTINCT TransactionId) AS ConversionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= #StartDate
AND GeneralJournal.[TransactionDate] <= #EndDate
AND MasterRecord = 0
AND TransactionTypeId = #SalesOrderTransactionTypeId
AND SEReferenceId > 0
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
Note that the second query returns distinct because it can return multiple values and we only want to count each TransactionId once in that scenario. These return the following results:
ReportingMonth
MonthNumber
ReportingYear
TransactionCount
November
11
2021
82
December
12
2021
49
January
1
2022
64
February
2
2022
67
March
3
2022
49
ReportingMonth
MonthNumber
ReportingYear
ConversionCount
November
11
2021
42
December
12
2021
27
January
1
2022
31
February
2
2022
50
March
3
2022
24
I actually need to combine them like this:
ReportingMonth
MonthNumber
ReportingYear
TransactionCount
ConversionCount
November
11
2021
82
42
December
12
2021
49
27
January
1
2022
64
31
February
2
2022
67
50
March
3
2022
49
24
I have tried pretty much everything I can think of - Unions, Joins, Subqueries - but so far nothing is quite right. This is the closest I can get:
SELECT
DATENAME(mm, GeneralJournal.[TransactionDate]) AS ReportingMonth,
DATEPART(mm, GeneralJournal.[TransactionDate]) AS MonthNumber,
DATEPART(yyyy, GeneralJournal.[TransactionDate]) AS ReportingYear,
SUM(CASE
WHEN TransactionTypeId = #SalesEstimateTransactionTypeId
AND MasterRecord = 1
THEN 1 ELSE 0
END) AS TransactionCount,
COUNT(CASE
WHEN TransactionTypeId = #SalesOrderTransactionTypeId
AND SEReferenceId > 0 THEN 1
END) AS ConversionCount
FROM
GeneralJournal
WHERE
GeneralJournal.[TransactionDate] >= #StartDate
AND GeneralJournal.[TransactionDate] <= #EndDate
AND TransactionTypeId IN (#SalesOrderTransactionTypeId, #SalesEstimateTransactionTypeId)
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm,GeneralJournal.[TransactionDate]);
However, I am unable to find a way to get a Distinct value for the ConversionCount. As a result it is returning the full count:
ReportingMonth
MonthNumber
ReportingYear
TransactionCount
ConversionCount
November
11
2021
82
152
December
12
2021
49
67
January
1
2022
64
101
February
2
2022
67
136
March
3
2022
49
64
Can anyone guide me towards a way to combine the two query results whilst maintaining the Distinct on the conversion count? I must add that for it to work the answer must be compatible with both SQL Server and VistaDB the syntax of which is a subset of T-SQL because I am obliged to support both database engines with the same query.
EDIT - The Final Solution
Following on from Nick's excellent answer I was able embed the solution into my existing query code to ensure that there are results even for months with no records, shown here in case it helps anyone else:
DECLARE #StartDate DATETIME = '2021-11-01T00:00:00';
DECLARE #EndDate DATETIME = '2022-10-31T23:59:59';
DECLARE #SalesEstimateTransactionTypeId INT = 16;
DECLARE #SalesOrderTransactionTypeId INT = 15;
DECLARE #CurrentDate DATETIME;
DECLARE #Months TABLE(ReportingYear INT, MonthNumber INT, ReportingMonth VARCHAR (40));
-- Set the initial date
SET #CurrentDate = #StartDate
-- insert all dates into temp table
WHILE #CurrentDate <= #EndDate
BEGIN
INSERT INTO #Months VALUES(DATEPART(year, #CurrentDate), DATEPART(month, #CurrentDate), DATENAME(mm, #CurrentDate))
SET #CurrentDate = dateadd(mm, 1, #CurrentDate)
END;
SELECT ReportingMonth, ReportingYear, Coalesce(TransactionCount, 0) AS TransactionCount, Coalesce(ConversionCount,0) AS ConversionCount
FROM
(
SELECT months.[ReportingMonth], months.[ReportingYear], conversionData.[TransactionCount], conversionData.[ConversionCount]
FROM #Months months
LEFT JOIN
(
SELECT
ReportingMonth = DATENAME(mm, GeneralJournal.[TransactionDate]),
MonthNumber = DATEPART(mm, GeneralJournal.[TransactionDate]),
ReportingYear = DATEPART(yyyy, GeneralJournal.[TransactionDate]),
TransactionCount = SUM(CASE WHEN TransactionTypeId = #SalesEstimateTransactionTypeId AND GeneralJournal.[MasterRecord] = 1 THEN
1
ELSE
0
END
),
ConversionCount = COUNT(DISTINCT CASE WHEN GeneralJournal.[TransactionTypeId] = #SalesOrderTransactionTypeId
AND GeneralJournal.[SEReferenceId] > 0
AND GeneralJournal.[MasterRecord] = 0 THEN
GeneralJournal.[TransactionID]
END
)
FROM GeneralJournal
WHERE GeneralJournal.[TransactionDate] >= #StartDate
AND GeneralJournal.[TransactionDate] <= #EndDate
AND GeneralJournal.[TransactionTypeId] IN ( #SalesOrderTransactionTypeId, #SalesEstimateTransactionTypeId)
GROUP BY
DATEPART(yyyy, GeneralJournal.[TransactionDate]),
DATEPART(mm, GeneralJournal.[TransactionDate]),
DATENAME(mm, GeneralJournal.[TransactionDate])
) as conversionData
ON months.[ReportingYear] = conversionData.[ReportingYear] AND months.[MonthNumber] = conversionData.[MonthNumber]
) AS data;
You can just put the two columns in the same query. It is made more complicated by the fact that the WHERE clauses are slightly different. SO you need to group, then group again, and use conditional aggregation to count the right rows for each column.
Note the following:
You could in theory do COUNT(DISTINCT CASE however that is normally slower as the compiler will not recognize what the CASE is doing and instead do a full sort.
It is faster to group by a single EOMONTH calculation to group by a whole month. You can pull out the year and month in the SELECT.
COUNT(TransactionId) will return the number of non-null TransactionId values. if TransactionId cannot be null then COUNT(*) is the same thing.
If TransactionDate has a time component then you should use a half-open interval >= AND <
Use aliases on tables, it makes your queries more readable.
Use whitepsace, it's free.
DECLARE #StartDate DATETIME = '2021-11-01T00:00:00';
DECLARE #EndDate DATETIME = '2022-03-17T00:00:00';
DECLARE #SalesEstimateTransactionTypeId INT = 16;
DECLARE #SalesOrderTransactionTypeId INT = 15;
SELECT
DATENAME(month, gj.mth) AS ReportingMonth,
DATEPART(month, gj.mth) AS MonthNumber,
DATEPART(year , gj.mth) AS ReportingYear,
SUM(TransactionCount) AS TransactionCount,
COUNT(CASE WHEN ConversionCount > 0 THEN 1 END) AS ConversionCount
FROM (
SELECT
EOMONTH(gj.TransactionDate) AS mth,
gj.TransactionId,
COUNT(CASE WHEN gj.MasterRecord = 1 AND gj.TransactionTypeId = #SalesEstimateTransactionTypeId THEN 1 END) AS TransactionCount,
COUNT(CASE WHEN gj.MasterRecord = 0 AND gj.TransactionTypeId = #SalesOrderTransactionTypeId AND gj.SEReferenceId > 0 THEN 1 END) AS ConversionCount
FROM GeneralJournal gj
WHERE gj.TransactionDate >= #StartDate
AND gj.TransactionDate < #EndDate
AND gj.TransactionTypeId IN (#SalesOrderTransactionTypeId, #SalesEstimateTransactionTypeId)
GROUP BY
EOMONTH(gj.TransactionDate),
TransactionId
) g
GROUP BY
mth;
Your second query that is close, I think just has a couple of minor omissions.
You forgot MasterRecord = 0 in your ConversionCount CASE statement.
Instead of returning 1 or 0 from your ConversionCount CASE you should return TransactionID or NULL so you can still count distinct values.
You are missing DISTINCT inside of your ConversionCount COUNT.
You will need to handle NULL values in the ConversionCount COUNT. I assumed you will always have at one or more NULLs, so I just subtract 1 from the COUNT(DISTINCT ...) to compensate.
(I can't be 100% on the syntax here without some example detail data to work with.)
Code
SELECT
ReportingMonth = DATENAME(mm, GeneralJournal.TransactionDate),
MonthNumber = DATEPART(mm, GeneralJournal.TransactionDate),
ReportingYear = DATEPART(yyyy, GeneralJournal.TransactionDate),
TransactionCount = SUM(CASE
WHEN TransactionTypeId = #SalesEstimateTransactionTypeId
AND MasterRecord = 1 THEN
1
ELSE
0
END
),
ConversionCount = COUNT(DISTINCT CASE
WHEN TransactionTypeId = #SalesOrderTransactionTypeId
AND SEReferenceId > 0
AND MasterRecord = 0 THEN
TransactionID
ELSE
NULL
END
) - 1 /* Subtract 1 for the NULL */
FROM GeneralJournal
WHERE
GeneralJournal.TransactionDate >= #StartDate
AND GeneralJournal.TransactionDate <= #EndDate
AND TransactionTypeId IN (
#SalesOrderTransactionTypeId,
#SalesEstimateTransactionTypeId
)
GROUP BY
DATEPART(yyyy, GeneralJournal.TransactionDate),
DATEPART(mm, GeneralJournal.TransactionDate),
DATENAME(mm, GeneralJournal.TransactionDate);

SQL Server - Use while loop to shorten several Union Joins

I have the following query that I simplified. Simply it displays a list of counts of records in the last 4 weeks.
SELECT COUNT(*) AS [Counts], Week=1
FROM TableA
WHERE Date >= DATEADD(week,-1,GETDATE())
AND Date <= GETDATE()
UNION
SELECT COUNT(*), 2
FROM TableA
WHERE Date >= DATEADD(week,-2,GETDATE())
AND Date <= DATEADD(week,-1,GETDATE())
UNION
SELECT COUNT(*), 3
FROM TableA
WHERE Date >= DATEADD(week,-3,GETDATE())
AND Date <= DATEADD(week,-2,GETDATE())
UNION
SELECT COUNT(*), 4
FROM TableA
WHERE Date >= DATEADD(week,-4,GETDATE())
AND Date <= DATEADD(week,-3,GETDATE())
Returns:
----------------
| Count | Week |
----------------
| 20 | 1 |
----------------
| 10 | 2 |
----------------
| 30 | 3 |
----------------
| 25 | 4 |
----------------
Suppose I want to modify the query so it returns the last 10 or 20 weeks.
How can I shorten the query so it loops through weeks?
e.g.
declare #w int;
set #w = 10;
while #w <> 0
begin
...;
--how can I do union joins?
set #w = #w - 1;
end
You could avoid UNION and specifying each week by hand by using GROUP BY:
SELECT datepart(week, Date) AS WeekNum, COUNT(*) AS counts
FROM TableA
WHERE Date >= DATEADD(week,-20,GETDATE()) -- num of weeks
GROUP BY datepart(week, Date); -- week of the year
If you need nums from 1 to n then:
WITH cte AS (
SELECT datepart(year, Date) AS [year],
datepart(week, Date) AS WeekNum,
COUNT(*) AS counts
FROM TableA
WHERE Date >= DATEADD(week,-20,GETDATE()) -- num of weeks
GROUP BY datepart(year, Date), datepart(week, Date)
)
SELECT ROW_NUMBER() OVER(ORDER BY [year] DESC, WeekNum DESC) AS WeekNum, counts
FROM cte;
EDIT:
"yes, like if today is wednesday, 20 week will give you a week starting in wednesday"
It could be handled by:
WHERE Date >= DATEADD(week,-20,GETDATE())
=>
WHERE Date >= DATEADD(week,-20,
CAST(DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), GETDATE()) AS DATE))

day wise and date range calculation

I am using Sql Server 2012.
This is how I calculate the ratio of failures in an order:
31 Days Table 1 query
sum(CASE
WHEN (datediff(dd,serDATE,'2015-01-21')) >= 31 THEN 31
WHEN (datediff(dd,serDATE,'2015-01-21')) < 0 THEN 0
ELSE (datediff(dd,serDATE,'2015-01-21'))END) as 31days
1 . How do i loop and pass dates dynamically in the Datediff?
31 Failures Table 2 query
SUM(Case when sometable.FAILUREDATE BETWEEN dateadd(DAY,-31,CONVERT(DATETIME, '2015-01-21 23:59:00.0', 102))
AND CONVERT(DATETIME, '2015-01-21 23:59:00.0', 102)Then 1 Else 0 END) As Failures31,
31 Day Cal(Formula)
((365*(Convert(decimal (8,1),T2.Failures31)/T1.31day))) [31dayCal]
This works fine when done for a specific order.
I want a similar kind of calculation done for day wise and month wise.
2. what approach should I be using to achieve day wise and month wise calculation?
I do also have a table called Calender with the list of dates that i can use.
I would really appreciate any help regarding this..Thank you..
Solution
DECLARE #StartDate date = 'Jan 1, 2015'
DECLARE #EndDate date = DATEADD(DAY, 30, #StartDate)
;WITH cte AS (
SELECT #StartDate AS ReportDate
UNION ALL
SELECT DATEADD(DAY, 1, ReportDate)
FROM cte
WHERE ReportDate < #EndDate
)
Select T1.[date],T1.Fail31,T2.days31,
((365*(Convert(decimal (8,1),T1.Fail31)/T2.days31))) [31Fly]
from
(
SELECT cte.ReportDate as [date],
SUM(Case when HISTORY.FAILUREDATE BETWEEN dateadd(DAY,-31,CONVERT(DATETIME, cte.ReportDate, 102))
AND CONVERT(DATETIME, cte.ReportDate, 102)Then 1 Else 0 END) As Fail31
FROM HISTORY left JOIN UNIT ON HISTORY.UNIT = UNIT.UNIT
CROSS JOIN cte
WHERE
UNIT.INSV_DATE < cte.ReportDate
AND UNIT.MODEL in('Toyota')
AND(UNIT.Customer in('Jona' ))
group by
cte.ReportDate ) T1
Inner Join
(SELECT cte.ReportDate as [date1],
COUNT(UNIT.UNIT) As Units,
sum(CASE
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) >= 31 THEN 31
WHEN (datediff(dd,INSV_DATE,cte.ReportDate)) < 0 THEN 0
ELSE (datediff(dd,INSV_DATE,cte.ReportDate))END) as days31
FROM UNIT
CROSS JOIN cte
WHERE
UNIT.INSV_DATE < cte.ReportDate
AND UNIT.MODEL in('Toyota')
AND(UNIT.Customer in('Jona' ))
group by
cte.ReportDate
) T2 on T1.[date] = t2.[date1]
Order by [date]

SQL Server: How to return value for each past 6 months

I have a query that returns a score on whether or not 3 of the columns = 1 and then if the ProviderID exists in the 2nd table. I need to be able to return a score for each month for 6 months using column Time_Stamp, not including current month. The below returns the score for last month. How can I include the remaining 5 months and ROW_NUMBER() them?
DECLARE #ProviderID int = '1717';
WITH cte as
(
SELECT TOP 1
a.ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted,
MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
FROM
ProviderValueCard a
LEFT JOIN
SubscriptionsTV b ON a.ProviderID = b.ProviderID
WHERE
a.ProviderID = #ProviderID AND GroupID = 2
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND DATEADD(DAY, -(DAY(GETDATE())), GETDATE())
GROUP BY
Time_Stamp, a.ProviderID, event
ORDER BY
event DESC, Time_Stamp DESC
)
SELECT
ProviderID, Time_Stamp,
(AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM
cte
Here is how to grab the first/last day of previous months:
2 months ago:
DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) as FirstD2monthsago,
DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -1, GETDATE())) AS last_day_2_months_ago
3 months ago etc:
DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 3, 0) as FirstD3monthsago,
DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -2, GETDATE())) AS last_day_3_months_ago
Desired output
ProviderID Time_Stamp TotalScore Row_Number
----------- ----------------------- -----------
1717 2014-08-29 12:11:17.610 70 1
1717 2014-07-29 12:11:17.610 95 2
1717 2014-06-29 12:11:17.610 100 3
1717 2014-05-29 12:11:17.610 70 4
1717 2014-04-29 12:11:17.610 70 5
1717 6
DECLARE #ProviderID INT, #Now DATETIME, #Months INT
SELECT #ProviderID = 1717, #Now = GETDATE(), #Months = 5
WITH
date_range_cte AS (
SELECT 1 AS RowNum, DATEADD(mm,-1,#Now) AS StartDate, DATEADD(mm,0,#Now) AS EndDate
UNION ALL
SELECT d.RowNum + 1 AS RowNum, DATEADD(mm,(-d.RowNum - 1),#Now) AS StartDate, DATEADD(mm,-d.RowNum,#Now) AS EndDate
FROM date_range_cte d
WHERE d.RowNum + 1 <= #Months
),
main_cte AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY a.ProviderID, d.RowNum, d.StartDate ORDER BY Time_Stamp DESC) AS ordinal_position,
a.ProviderID,
d.RowNum,
d.StartDate,
[AdditionalReports] * 5 AS AdditionalReports,
[UniqueReportRequests] * 15 AS UniqueReportsRequests,
[SurveyCompleted] * 30 as SurveyCompleted,
CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END as SubscriptionExists
FROM ProviderValueCard a
INNER JOIN date_range_cte d ON d.StartDate < Time_Stamp AND Time_Stamp <= d.EndDate
LEFT OUTER JOIN SubscriptionsTV b ON a.ProviderID = b.ProviderID
WHERE a.ProviderID = #ProviderID AND GroupID = 2
)
SELECT ProviderID, RowNum, StartDate, (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM main_cte
WHERE ordinal_position = 1
ORDER BY RowNum
Here's a couple of ways (psuedocode):
1 - Make a cte just like your existing one for each month you want to get. The only thing you need to change in each one is this line:
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND DATEADD(DAY, -(DAY(GETDATE())), GETDATE())
For 2 months ago, you would change it to this:
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) AND DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)
and so on for the other months back.
2 - Referring to the same line in your cte above, change it to a -6 to get data for the past 6 months. Then include a MONTH(TimeStamp) column in your select list and group by it to get one row per month for the past 6 months.

How to display month name in different columns in sql using datediff function

I have this query:
DECLARE #month INT
SET #month=1
SELECT
CLOI_ClientOrderItems.cl_Id,
NoOfInv = SUM(CASE WHEN DATEPART(mm, in_date_issued) <= #month
AND DATEPART(yyyy, in_date_issued) = 2014
THEN 1 ELSE 0 END),
MonthTotal = SUM(CASE WHEN DATEPART(mm, in_date_issued) <= #month
AND DATEPART(yyyy, in_date_issued) = 2014
THEN in_total ELSE 0 END),
Grandtotal = SUM(in_total),
RemainingAmount = SUM(in_total) - SUM(CASE
WHEN DATEPART(mm, in_date_issued) <= #month
THEN in_total ELSE 0 END)
FROM (SELECT
DISTINCT MasterOrderId, cl_Id
FROM
CLOI_ClientOrderItems) as CLOI_ClientOrderItems
INNER JOIN
IN_Invoices
ON
IN_Invoices.MasterOrderId = CLOI_ClientOrderItems.MasterOrderId
GROUP BY
CLOI_ClientOrderItems.cl_id
i want output like
noofinv |amt |clid | grandtotal | jan |feb |march |remainingamt
5 |7.00 |100000_Pri | 245.00 | 0.00 |238.00 |7.00 |238.00
12 |2510.12 |100001_pro | 181110.29 | 138891.92 |9708.25 |510.12 |178600.17
If I pass month number like 3, it should display it as like Jan Feb and March and its related records in the respective month.
Try this, where condition is useful for you.
select Datename(mm,in_date_issued) from IN_Invoices Where Datediff(yyyy,in_date_issued,3) = 2014 and Datediff(mm,in_date_issued,#monthParameter) <= 3
You can Try like This...
declare #MonthCount int=1
SELECT DATENAME(month, DATEADD(month, #MonthCount-1 ,
CAST('2014-01-01' AS datetime))) as Month_Name
OP:
Month_Name
January

Resources