Display Month Gaps for Each location - sql

I have the following query which takes in the opps and calculates the duration, and revenue for each month. However, for some locations, where there is no data, it is missing some months. Essentially, I would like all months to appear for each of the location and record type. I tried a left outer join on the calendar but that didn't seem to work either.
Here is the query:
;With DateSequence( [Date] ) as
(
Select CAST(#fromdate as DATE) as [Date]
union all
Select CAST(dateadd(day, 1, [Date]) as Date)
from DateSequence
where Date < #todate
)
INSERT INTO CalendarTemp (Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;
DELETE FROM CalendarTemp WHERE DayOfWeek IN ('Saturday', 'Sunday');
SELECT
AccountId
,AccountName
,Office
,Stage = (CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,RecordType= (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Start_Date
,End_Date
,Probability
,Estimated_Revenue_Won = ISNULL(Amount, 0)
,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) AS Row
--,Revenue_Per_Day = CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,YEAR(c.Date) as year
,MONTH(c.Date) as Month
,c.MonthName
--, ISNULL(CAST(Sum((Amount)/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0)) as money),0) As RevenuePerMonth
FROM SF_Extracted_Opps o
LEFT OUTER JOIN CalendarTemp c on o.Start_Date <= c.Date AND o.End_Date >= c.Date
WHERE
Start_Date <= #todate AND End_Date >= #fromdate
AND Office IN (#Location)
AND recordtypeid IN ('LAS1')
GROUP BY
AccountId
,AccountName
,Office
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,(CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Amount
--, CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,Start_Date
,End_Date
,Probability
,YEAR(c.Date)
,Month(c.Date)
,c.MonthName
,dbo.CalculateNumberOFWorkDays(Start_Date, End_Date)
ORDER BY Office
, (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
, [Start_Date], Month(c.Date), AccountName, Row;
I tried adding another left outer join to this and using this a sub query and the join essentially on the calendar based on the year and month, but that did not seem to work either. Suggestions would be extremely appreciated.
--Date Calendar for each location:
;With DateSequence( [Date], Locatio) as
(
Select CAST(#fromdate as DATE) as [Date], oo.Office as location
union all
Select CAST(dateadd(day, 1, [Date]) as Date), oo.Office as location
from DateSequence dts
join Opportunity_offices oo on 1 = 1
where Date < #todate
)
--select result
INSERT INTO CalendarTemp (Location,Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
location,
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;

you have your LEFT JOIN backwards if you want all records from CalendarTemp and only those that match from SF_Extracted_Opps then you the CalendarTemp should be the table on the LEFT. You can however switch LEFT JOIN to RIGHT JOIN and it should be fixed. The other issue will be your WHERE statement is using columns from your SF_Extracted_Opps table which will just make that an INNER JOIN again.
here is one way to fix.
SELECT
.....
FROM
CalendarTemp c
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= #todate AND End_Date >= #fromdate
AND o.Office IN (#Location)
AND o.recordtypeid IN ('LAS1')
The other issue you might run into is because you remove weekends from your CalendarTemp Table not all dates are represented I would test with the weekends still in and out and see if you get different results.
this line:
AND o.Start_Date <= #todate AND End_Date >= #fromdate
should not be needed either because you are already limiting the dates from the line before and values in your CalendarTempTable
A note about your CalendarDate table you don't have to go back and delete those records simply add the day of week as a WHERE statement on the select that populates that table.
Edit for All Offices you can use a cross join of your offices table with your CalendarTemp table to do this do it in your final query not the cte that builds the calendar. The problem with doing it in the CTE calendar definition is that it is recursive so you would have to do it in both the anchor and the recursive member definition.
SELECT
.....
FROM
CalendarTemp c
CROSS JOIN Opportunity_offices oo
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= #todate AND End_Date >= #fromdate
AND oo.office = o.Office
AND o.recordtypeid IN ('LAS1')

Related

SQL group by - How to get new records that did not exist in any previous month

I have the following data.
DECLARE #Table TABLE(
RequestID varchar(100)
, PersonID varchar(100)
, StartDate DATE
, EndDate DATE
, StatusType VARCHAR(150)
)
INSERT INTO #Table
SELECT '445566', 'Person2', '9/13/2022', '9/16/2022', 'TransactionStarted'
UNION ALL
SELECT '445566', 'Person2', '9/13/2022', '9/16/2022', 'TransactionEnded'
UNION ALL
SELECT '112233', 'Person2', '8/13/2022', '8/16/2022', 'TransactionStarted'
UNION ALL
SELECT '112233', 'Person2', '8/13/2022', '8/16/2022', 'TransactionEnded'
UNION ALL
SELECT '556677', 'Person1', '8/10/2022', '8/12/2022', 'TransactionStarted'
UNION ALL
SELECT '556677', 'Person1', '8/10/2022', '8/12/2022', 'TransactionEnded'
I get the data out like this, and it works well
SELECT COUNT(Distinct RequestID) TotalCountPerPerson, DATENAME(mm, StartDate) [SRMonthName], MONTH(StartDate) [SRMonthNumber], YEAR(StartDate) [SRYear]
FROM #Table
GROUP BY MONTH(StartDate), DATENAME(mm,StartDate), YEAR(StartDate)
ORDER BY YEAR(StartDate), MONTH(StartDate)
But, I need an additional point of data that I am having trouble figuring out how to get. In the sample data, You can see that "Person 2" and "Person1" were both "new" to the system in August. I need a way to add them to the query so that I can get Total Count and New Count per month and year. Anyone help with the query?
SELECT 2 TotalCountPerPerson, 2 NewThisMonth, 'August'[SRMonthName], 8 [SRMonthNumber], 2022 [SRYear]
UNION ALL
SELECT 1, 0 NewThisMonth,'September', 9, 2022
You may use a self left join as the following:
SELECT COUNT(Distinct T.PersonID) TotalCountPerPerson,
COUNT(Distinct CASE WHEN D.PersonID IS NULL THEN T.PersonID END) NewThisMonth,
DATENAME(mm, T.StartDate) [SRMonthName],
MONTH(T.StartDate) [SRMonthNumber], YEAR(T.StartDate) [SRYear]
FROM #Table T LEFT JOIN #Table D
ON T.PersonID = D.personID AND T.StartDate > D.StartDate
GROUP BY MONTH(T.StartDate), DATENAME(mm,T.StartDate), YEAR(T.StartDate)
ORDER BY YEAR(T.StartDate), MONTH(T.StartDate)
Also, you may use EXISTS operator as the following:
WITH CTE AS
(
SELECT *, CASE WHEN NOT EXISTS
(SELECT 1 FROM #Table D WHERE D.PersonID = T.PersonID AND D.StartDate<T.StartDate)
THEN T.PersonID
END AS ISNEW
FROM #Table T
)
SELECT COUNT(Distinct PersonID) TotalCountPerPerson,
COUNT(Distinct ISNEW) NewThisMonth,
DATENAME(mm, StartDate) [SRMonthName],
MONTH(StartDate) [SRMonthNumber], YEAR(StartDate) [SRYear]
FROM CTE
GROUP BY MONTH(StartDate), DATENAME(mm,StartDate), YEAR(StartDate)
ORDER BY YEAR(StartDate), MONTH(StartDate);
See a demo.

How Can I write in my code to exclude accounts that have had a payment posted w/in last 45 days?

I'm working in SQL Server Mgmt Studio and I'm trying to identify accounts that have not had a payment posted since the last 45 days. I've tried declaring a min and max date with getdate being less than 45 days, but that didnt work. I've also tried stating "where last payment !> getdate() -45".... but this did not give me the results I was looking for. what I need the query to do is only identify accounts that truly have not had a payment post in the last 45 days. but I'm not sure how to state this in my where clause. Here's my query
DECLARE #minDate datetime;
DECLARE #maxDate datetime;
SET #minDate = GETDATE();
SET #maxDate = GETDATE() - 45;
SELECT DISTINCT
a.id,
a.FacilityCode AS [Facility],
a.accountUnit,
a.accountNum AS [Account Number],
a.amountBalance AS [Balance],
a.accountstatus AS [Status],
CONVERT(date, a.accountStatusDate) AS StatusDate,
pmtEntryDate AS [Pmt Entry Date],
v.LastLinkARpmtDate AS [Last Pmt Date],
CONVERT(date, a.accountnextactdate) AS NextActionDate,
CONVERT(date, a.rpcDate) AS RightpartyContactDate,
a.flag AS accountFlag,
pay.flag AS pmtFlag,
a.accounttype
FROM dbo.tbAccount a
JOIN dbo.tbpmtinfo pay ON a.id = pay.id
JOIN dbo.vLastPmtDate v ON v.id = a.id
FULL JOIN (SELECT id,
MAX(deDate) AS MFSLoadDate
FROM dbo.tbDataEvents (NOLOCK)
WHERE deNewVal = 'MFS'
GROUP BY id) m ON m.id = a.id
WHERE pay.flag IN ('D')
AND a.amountBalance > 0
AND a.FacilityCode IN ('PHKY', 'QANM', 'QAOH', 'QBCA', 'QBIL', 'QBTX', 'QCIL', 'QDAL', 'QEWY', 'QFAR', 'QFGA',
'QGIL', 'QHAR', 'QHIL', 'QHTN', 'QLAL', 'QLPA', 'QMIL', 'QMNC', 'QMNM', 'QMNV', 'QMOR',
'QMTN', 'QMTX', 'QMUT', 'QRIL', 'QRKY', 'QSPA', 'QTGA', 'QTKY', 'QUIL', 'QVIL', 'QWIL', 'LHFL')
AND a.amountBalance >= '1000'
AND a.accountStatus IN ('PA', 'PP', 'BPA')
AND a.flag = 'A'
AND a.accountType IN ('Resid', 'Slfpy')
--and LastLinkARpmtDate !> Getdate() -45 and accountNum = '40728597'
AND LastLinkARpmtDate BETWEEN #minDate AND #maxDate;
I would use a WHERE NOT EXISTS clause to eliminate recent activity:
SELECT DISTINCT a.id
,a.FacilityCode [Facility]
,a.accountUnit
,a.accountNum [Account Number]
,a.amountBalance [Balance]
,a.accountstatus [Status]
,convert(DATE, a.accountStatusDate) StatusDate
,pmtEntryDate [Pmt Entry Date]
,v.LastLinkARpmtDate [Last Pmt Date]
,convert(DATE, a.accountnextactdate) NextActionDate
,convert(DATE, a.rpcDate) RightpartyContactDate
,a.flag AS accountFlag
,pay.flag AS pmtFlag
,a.accounttype
FROM dbo.tbAccount AS a
JOIN dbo.tbpmtinfo AS pay ON a.id = pay.id
JOIN dbo.vLastPmtDate AS v ON v.id = a.id
FULL JOIN (
SELECT id
,Max(deDate) AS MFSLoadDate
FROM dbo.tbDataEvents(NOLOCK)
WHERE deNewVal = 'MFS'
GROUP BY id
) m ON m.id = a.id
WHERE pay.flag IN ('D')
AND a.amountBalance > 0
AND a.FacilityCode IN (
'PHKY'
,'QANM'
,'QAOH'
,'QBCA'
,'QBIL'
,'QBTX'
,'QCIL'
,'QDAL'
,'QEWY'
,'QFAR'
,'QFGA'
,'QGIL'
,'QHAR'
,'QHIL'
,'QHTN'
,'QLAL'
,'QLPA'
,'QMIL'
,'QMNC'
,'QMNM'
,'QMNV'
,'QMOR'
,'QMTN'
,'QMTX'
,'QMUT'
,'QRIL'
,'QRKY'
,'QSPA'
,'QTGA'
,'QTKY'
,'QUIL'
,'QVIL'
,'QWIL'
,'LHFL'
)
AND a.amountBalance >= '1000'
AND a.accountStatus IN (
'PA'
,'PP'
,'BPA'
)
AND a.flag = 'A'
AND a.accountType IN (
'Resid'
,'Slfpy'
)
AND NOT EXISTS (
SELECT NULL
FROM vLastPmtDate
WHERE v.id = a.id
AND CAST(v.LastLinkARpmtDate AS DATE) > CAST(dateadd(day, - 45, getdate() AS DATE))
)
AND accountNum = '40728597'
AND LastLinkARpmtDate BETWEEN #minDate
AND #maxDate;
The function dateadd() is what you need:
DATEADD (datepart , number , date)
Set #maxDate = DATEADD(DAY, -45, GETDATE());

SQL - result fom weekday(time) and from week(without-Time)

I'm trying to solve the problem. I need to get results from a working week (working hours are specified, for example, from 7:00 am to 8:00 pm), and I need to include weekends results (without specified time). But I dont know how to solve problem with weekday and include to result
select
c.PatientId
,g.PatientId
,c.StartDate
,g.TransferOrdinalNumber
from ClinicalEvent C
join PatientIncomming G on C.PatientId=G.PatientId
where
(DATEPART(dw, StartDate) in (1,2,3,4,5))
and (
(CAST(StartDate as Time) between '20:00' and '23:59')
or
(CAST(StartDate as Time) between '00:01' and '07:00')
)
and StartDate between '2020.02.01' and '2020.2.28'
and EventTypeId = '5365f53c-583b-4b53-bf50-2ec7c002e53c'
and g.TransferOrdinalNumber=1
group by C.PatientId, G.PatientId, c.StartDate, g.TransferOrdinalNumber
order by C.PatientId, G.PatientId
You can use UNION ALL statement can be helpful in the very basic method.
select
c.PatientId
,g.PatientId
,c.StartDate
,g.TransferOrdinalNumber
from ClinicalEvent C
join PatientIncomming G on C.PatientId=G.PatientId
where
(DATEPART(dw, StartDate) in (1,2,3,4,5))
and (
(CAST(StartDate as Time) between '20:00' and '23:59')
or
(CAST(StartDate as Time) between '00:01' and '07:00')
)
and StartDate between '2020.02.01' and '2020.2.28'
and EventTypeId = '5365f53c-583b-4b53-bf50-2ec7c002e53c'
and g.TransferOrdinalNumber=1
group by C.PatientId, G.PatientId, c.StartDate, g.TransferOrdinalNumber
UNION ALL
select
c.PatientId
,g.PatientId
,c.StartDate
,g.TransferOrdinalNumber
from ClinicalEvent C
join PatientIncomming G on C.PatientId=G.PatientId
where
(DATEPART(dw, StartDate) in (6,7))
--and (
--(CAST(StartDate as Time) between '20:00' and '23:59')
--or
--(CAST(StartDate as Time) between '00:01' and '07:00')
--)
and StartDate between '2020.02.01' and '2020.2.28'
and EventTypeId = '5365f53c-583b-4b53-bf50-2ec7c002e53c'
and g.TransferOrdinalNumber=1
group by C.PatientId, G.PatientId, c.StartDate, g.TransferOrdinalNumber
order by C.PatientId, G.PatientId

Taking most recent values in sum over date range

I have a table which has the following columns: DeskID *, ProductID *, Date *, Amount (where the columns marked with * make the primary key). The products in use vary over time, as represented in the image below.
Table format on the left, and a (hopefully) intuitive representation of the data on the right for one desk
The objective is to have the sum of the latest amounts of products by desk and date, including products which are no longer in use, over a date range.
e.g. using the data above the desired table is:
So on the 1st Jan, the sum is 1 of Product A
On the 2nd Jan, the sum is 2 of A and 5 of B, so 7
On the 4th Jan, the sum is 1 of A (out of use, so take the value from the 3rd), 5 of B, and 2 of C, so 8 in total
etc.
I have tried using a partition on the desk and product ordered by date to get the most recent value and turned the following code into a function (Function1 below) with #date Date parameter
select #date 'Date', t.DeskID, SUM(t.Amount) 'Sum' from (
select #date 'Date', t.DeskID, t.ProductID, t.Amount
, row_number() over (partition by t.DeskID, t.ProductID order by t.Date desc) as roworder
from Table1 t
where 1 = 1
and t.Date <= #date
) t
where t.roworder = 1
group by t.DeskID
And then using a utility calendar table and cross apply to get the required values over a time range, as below
select * from Calendar c
cross apply Function1(c.CalendarDate)
where c.CalendarDate >= '20190101' and c.CalendarDate <= '20191009'
This has the expected results, but is far too slow. Currently each desk uses around 50 products, and the products roll every month, so after just 5 years each desk has a history of ~3000 products, which causes the whole thing to grind to a halt. (Roughly 30 seconds for a range of a single month)
Is there a better approach?
Change your function to the following should be faster:
select #date 'Date', t.DeskID, SUM(t.Amount) 'Sum'
FROM (SELECT m.DeskID, m.ProductID, MAX(m.[Date) AS MaxDate
FROM Table1 m
where m.[Date] <= #date) d
INNER JOIN Table1 t
ON d.DeskID=t.DeskID
AND d.ProductID=t.ProductID
and t.[Date] = d.MaxDate
group by t.DeskID
The performance of TVF usually suffers. The following removes the TVF completely:
-- DROP TABLE Table1;
CREATE TABLE Table1 (DeskID int not null, ProductID nvarchar(32) not null, [Date] Date not null, Amount int not null, PRIMARY KEY ([Date],DeskID,ProductID));
INSERT Table1(DeskID,ProductID,[Date],Amount)
VALUES (1,'A','2019-01-01',1),(1,'A','2019-01-02',2),(1,'B','2019-01-02',5),(1,'A','2019-01-03',1)
,(1,'B','2019-01-03',4),(1,'C','2019-01-03',3),(1,'B','2019-01-04',5),(1,'C','2019-01-04',2),(1,'C','2019-01-05',2)
GO
DECLARE #StartDate date=N'2019-01-01';
DECLARE #EndDate date=N'2019-01-05';
;WITH cte_p
AS
(
SELECT DISTINCT DeskID,ProductID
FROM Table1
WHERE [Date] <= #EndDate
),
cte_a
AS
(
SELECT #StartDate AS [Date], p.DeskID, p.ProductID, ISNULL(a.Amount,0) AS Amount
FROM (
SELECT t.DeskID, t.ProductID
, MAX(t.Date) AS FirstDate
FROM Table1 t
WHERE t.Date <= #StartDate
GROUP BY t.DeskID, t.ProductID) f
INNER JOIN Table1 a
ON f.DeskID=a.DeskID
AND f.ProductID=a.ProductID
AND f.[FirstDate]=a.[Date]
RIGHT JOIN cte_p p
ON p.DeskID=a.DeskID
AND p.ProductID=a.ProductID
UNION ALL
SELECT DATEADD(DAY,1,a.[Date]) AS [Date], t.DeskID, t.ProductID, t.Amount
FROM Table1 t
INNER JOIN cte_a a
ON t.DeskID=a.DeskID
AND t.ProductID=a.ProductID
AND t.[Date] > a.[Date]
AND t.[Date] <= DATEADD(DAY,1,a.[Date])
WHERE a.[Date]<#EndDate
UNION ALL
SELECT DATEADD(DAY,1,a.[Date]) AS [Date], a.DeskID, a.ProductID, a.Amount
FROM cte_a a
WHERE NOT EXISTS(SELECT 1 FROM Table1 t
WHERE t.DeskID=a.DeskID
AND t.ProductID=a.ProductID
AND t.[Date] > a.[Date]
AND t.[Date] <= DATEADD(DAY,1,a.[Date]))
AND a.[Date]<#EndDate
)
SELECT [Date], DeskID, SUM(Amount)
FROM cte_a
GROUP BY [Date], DeskID;

Pivot and INNER JOINs

I have been trying to run a pivot query but I am failing hard, I am very new with all this so please be patient
what I want is to return the Quantities values of each month, jan, feb... dec, for each PartRef
this is what I have
SELECT PartRef
, Year
, fMonth
, sum(Quantity) as Quantity
FROM(SELECT PartRef
, year(DateClosed) as Year
, month(DateClosed) as Month
, SUM(fldShipped) as Quantity
FROM PartsInvoice
INNER JOIN Requests ON PartsInvoice.fID = Requests.WorkItemRef
INNER JOIN PartsLine ON Requests.ID = PartsLine.RequestRef
WHERE Closed = 1 and DateClosed > DateAdd(mm, DateDiff(mm, 0, GetDate()) -12, 0)
GROUP BY PartRef, year(DateClosed), month(DateClosed)
) as SalesHits
PIVOT (
SUM(NOT SURE)FOR NOT SURE IN ([Jan],[Feb],[Mar],[Apr],[May],[June],[July],[Ago],[Sep],[Oct],[Nov],[Dec])
)AS Hits
GROUP BY PartRef, Year, Month
Here you have an example how it works with a table like yours.
declare #table table(
partref int,
year int,
month nvarchar(50),
quantity int
)
insert into #table values
(1,2016,'jan',12),
(1,2016,'feb',12),
(2,2016,'jan',12),
(2,2016,'feb',12),
(1,2016,'jan',12)
select PartRef
, year
, sum([jan]) 'Jan',sum([feb]) 'Feb'
,sum([mar]),sum([apr]),sum([may]),sum([jun]),sum([jul])
,sum([aug]),sum([sep]),sum([oct]),sum([nov]),sum([dec])
from(
SELECT PartRef
, year
, [jan],[feb],[mar],[apr],[may],[jun],[jul],[aug],[sep],[oct],[nov],[dec]
from #table
PIVOT (
SUM(quantity)FOR month IN ([jan],[feb],[mar],[apr],[may],[jun],[jul],[aug],[sep],[oct],[nov],[dec])
)AS Hits
) as t
group by PartRef,year
here is the full scope of my query and I believe I got it to work :)
SELECT *
FROM(SELECT PartRef
, year(DateClosed) as Year
, month(DateClosed) as Month
, SUM(Shipped) as Quantity
FROM PartsInvoice
INNER JOIN Requests ON PartsInvoice.ID = Requests.WorkItemRef
INNER JOIN PartsLine ON Requests.ID = PartsLine.RequestRef
WHERE HasClosed = 1 and DateClosed > DateAdd(mm, DateDiff(mm, 0, GetDate()) -13, 0)
GROUP BY PartRef, year(DateClosed), month(DateClosed)
UNION ALL
--RO
SELECT PartRef
, year(DateClosed) as Year
, month(DateClosed) as Month
, SUM(Shipped) as Quantity
FROM RepairOrder
INNER JOIN Requests ON RepairOrder.ID = Requests.WorkItemRef
INNER JOIN PartsLine ON Requests.ID = PartsLine.RequestRef
WHERE Status = 3 and DateClosed > DateAdd(mm, DateDiff(mm, 0, GetDate()) -13, 0)
GROUP BY PartRef, year(DateClosed), month(DateClosed)
UNION ALL
-- Historical Hits
SELECT PartRef
, year(date) as Year
, month(Date) as Month
, SUM(Quantity) as Quantity
FROM PartsHistoricalHits
WHERE Date > DateAdd(mm, DateDiff(mm, 0, GetDate()) -13, 0)
GROUP BY PartRef, year(Date), month(Date)
) as SalesHits
PIVOT (
COUNT (Quantity)FOR fldMonth IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
)AS Hits