SQL Reporting Aggregates and Joining Issues - sql

I am attempting to create a report for orders moving through the various actions on a weekly basis. Could you guys help me out with it?
The desired report (simple ...right):
Week Of Action 1 Action 2 Action 3
---------- -------- -------- --------
2011-11-07 34 55 35
2011-11-14 34 55 35
And here is what I have tried so far, all of which have been miserable failures:
CREATE TABLE WorkOrderHistory
(
WorkOrderHistoryID int, --PK
WorkOrderActionID int,
DateCompleted datetime
)
CREATE TABLE WorkOrderAction
(
WorkOrderActionID int --PK
)
DECLARE
#StartDate DateTime,
#EndDate DateTime,
#SeasonID int;
SET #SeasonID = 16;
SELECT #StartDate = '2011-09-01',
#EndDate = ISNULL((SELECT TOP 1 StartDate FROM Season WHERE SeasonID > #SeasonID), GETDATE()) -- End date will be set to the current date if no season exists beyond the current
--Method 3 Inner Joins. This fails because of my attempt to join on the WeekOf alias to the DATEADD function
SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101') AS WeekOf,
ArtworkCapture.WOsProcessed AS ArtworkCapture
FROM WorkOrderHistory WOH (NOLOCK)
INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
INNER JOIN (SELECT COUNT (*) AS WOsProcessed,
DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101') AS WeekOf
FROM WorkOrderHistory WOH (NOLOCK) INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
AND WOH.WorkOrderActionID = 1 --Artwork Capture
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101')) ArtworkCapture ON WOH.WeekOf = ArtworkCapture.WeekOf
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101')
ORDER BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101')
--Method 2 Subqueries. I can not figure out how to properly form this query.
SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101') AS WeekOf,
(SELECT COUNT (*)
FROM WorkOrderHistory WOH (NOLOCK) INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
AND WOH.WorkOrderActionID = 1 --Artwork Capture
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101'))
AS ArtworkCapture,
(SELECT COUNT (*)
FROM WorkOrderHistory WOH (NOLOCK) INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
AND WOH.WorkOrderActionID = 3 --Art Entry
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101'))
AS ArtEntry
FROM WorkOrderHistory WOH (NOLOCK) INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101')
ORDER BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101')
--This query gives me all of the data I need but it is not aggregated, so there is a record for each action per week so [2011-11-07 - 1 - 34], [2011-11-14 - 1 - 34], [2011-11-07 - 2 - 55], [2011-11-14 - 1 - 55].
SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101') AS WeekOf,
WOA.WorkOrderActionID, COUNT (*) AS WorkOrdersProcessed
FROM WorkOrderHistory WOH (NOLOCK) INNER JOIN WorkOrderAction WOA (NOLOCK) ON WOH.WorkOrderActionID = WOA.WorkOrderActionID
WHERE WOH.DateCompleted >= #StartDate AND WOH.DateCompleted < #EndDate
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101'), WOA.WorkOrderActionID
ORDER BY DATEADD(WEEK, DATEDIFF(WEEK, '19000101', WOH.DateCompleted), '19000101'), WOA.WorkOrderActionID

Looks Like you want to convert rows into columns. You don't need to use sub queries use either Pivot (for SQL 2005+) or SUM/CASE.
Notes: I didn't bother with the Week Calculation since you already have that. I also added a name for WorkOrderAction, since I assume you have that rather than just an ID
Declare #WorkOrderHistory as table
(
WorkOrderHistoryID int, --PK
WorkOrderActionID int,
DateCompleted datetime
)
declare #WorkOrderAction as TABLE
(
WorkOrderActionID int, --PK
Name varchar (50)
)
Insert into #WorkOrderAction
Values (1, 'Action1'),
(2, 'Action2'),
(3, 'Action3')
INSERT INTO #WorkOrderHistory
VALUES (1, 1, '2011-11-07'),
(2, 1, '2011-11-07'),
(3, 1, '2011-11-07'),
(4, 2, '2011-11-07'),
(5, 3, '2011-11-07'),
(6, 3, '2011-11-07'),
(8, 2, '2011-11-14'),
(9, 2, '2011-11-14'),
(10, 2, '2011-11-14'),
(11, 3, '2011-11-14'),
(12, 3, '2011-11-14'),
(13, 1, '2011-11-14')
SELECT datecompleted,
action1,
action2,
action3
FROM (SELECT woa.name,
COUNT(woh.workorderhistoryid) AS kount,
datecompleted
FROM #WorkOrderHistory woh
INNER JOIN #workOrderAction woa
ON woh.workorderactionid = woa.workorderactionid
GROUP BY woa.name,
datecompleted ) p PIVOT ( SUM(kount) FOR p.name IN (
[Action1],
[Action2], [Action3] ) ) AS pvt ​
Produces this result
datecompleted action1 action2 action3
------------------ ------- ------- -------
2011-11-07 0:00:00 3 1 2
2011-11-14 0:00:00 1 3 2
see sample at data exchange

Related

SQL Temp Table Cost 75% Insert

I have been looking for ways to reduce this Table Insert cost down from 75%. The one way that I was thinking we be to create the temp table before the insert but that didnt help is there any other way to improve insert into Temp Table.
#StartDate date = null,
#EndDate date = null
IF #StartDate IS NULL AND #EndDate IS NULL
BEGIN
SET #StartDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + -12, 0)
SET #EndDate = DATEADD(MILLISECOND, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
END
SELECT CustomerId, LogDate, StartDate = #StartDate, EndDate = #EndDate
INTO #Temp1
FROM Log l
where l.LogDate >= #StartDate and l.LogDate < dateadd(day, 1, #EndDate)
select
l.*,
a.StateId,
a.CountryId
into #Temp
from #Temp1 l
JOIN [Address] a ON a.CustomerId = l.CustomerId

SQL Server grouped rows return with default values if no row available for a date period

I'm trying to write a stored procedure which groups up rows based on their month and return a sum of all items if they exist and 0 if they don't.
For the date part of the query, what I am trying to get is today's date - extract the month and go back 5 months to gather any data if it exists.
At this stage, the query runs fine as is but I'm wondering if there's any way to optimise this as it looks like I'm running the same set of data over and over again and also it's hard coded to an extent.
The dataset I am trying to achieve is as follows:
Month TotalAmount TotalCount
-----------------------------------
2017-11 0 0
2017-12 200.00 2
2018-01 300.00 3
2018-02 0 0
2018-03 300.00 3
2018-04 100.00 1
Using the following query below, I was able to achieve what I want but as you can see, it's hard coding back the past 5 months so if I wanted to go back 12 months, I'd have to add in more code.
DECLARE #5MonthAgo date = CAST(DATEADD(MONTH, -5, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -5, GETDATE())) AS DATE)
DECLARE #4MonthAgo date = CAST(DATEADD(MONTH, -4, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -4, GETDATE())) AS DATE)
DECLARE #3MonthAgo date = CAST(DATEADD(MONTH, -3, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -3, GETDATE())) AS DATE)
DECLARE #2MonthAgo date = CAST(DATEADD(MONTH, -2, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -2, GETDATE())) AS DATE)
DECLARE #1MonthAgo date = CAST(DATEADD(MONTH, -1, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -1, GETDATE())) AS DATE)
DECLARE #CurrentMonth date = CAST(GETDATE() + 1 - DATEPART(DAY, GETDATE()) AS DATE)
-- Table to return grouped and sum data
DECLARE #StatsTable TABLE ([Month] DATE,
[Total Amount] DECIMAL(18,2),
[Total Count] INT
)
-- Temporary table to hold onto data batch - so table isn't used later on
DECLARE #TempGenTable TABLE ([Id] INT,
[Date] DATETIME,
[Lines] INT NULL,
[Amount] DECIMAL(18, 2) NULL
)
INSERT INTO #TempGenTable
SELECT
Id, Date, Lines, Amount
FROM
TallyTable
WHERE
Date >= #5MonthAgo
INSERT INTO #StatsTable
SELECT
#5MonthAgo,
COALESCE((SELECT SUM(Amount)
FROM #TempGenTable
WHERE Date >= #5MonthAgo AND Date < #4MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0),
COALESCE((SELECT COUNT(Id)
FROM #TempGenTable
WHERE Date >= #5MonthAgo AND Date < #4MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0)
UNION
SELECT
#4MonthAgo,
COALESCE((SELECT SUM(Amount)
FROM #TempGenTable
WHERE Date >= #4MonthAgo AND Date < #3MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0),
COALESCE((SELECT COUNT(Id)
FROM #TempGenTable
WHERE Date >= #4MonthAgo AND Date < #3MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0)
...
Is there an easier way to be able to get the above data with more flexibility in the number of months?
Is it better to just have the query pass in a month variable and it checks just the current month and have a loop within the controller to go back x number of months?
I would generate the data using a recursive CTE and then use left join:
with months as (
select datefromparts(year(getdate()), month(getdate()), 1) as month_start, 5 as n
union all
select dateadd(month, -1, month_start), n - 1
from months
where n > 0
)
select m.month_start, count(s.id), sum(s.amount)
from months m left join
#StatsTable s
on m.month_start = s.month
group by m.month_start
order by m.month_start;
You haven't provided sample data, so I'm not sure what s.month looks like. You might want the join condition to be:
on s.month >= m.month_start and s.month < dateadd(month, 1, m.month_start)
Below is a set-based method to generate the needed monthly periods:
--sample data
CREATE TABLE dbo.TallyTable (
Id int
, Date datetime
, Lines int
, Amount decimal(18, 2)
);
INSERT INTO dbo.TallyTable
VALUES
(1, '2017-12-05', 1, 50.00)
,(2, '2017-12-06', 1, 150.00)
,(3, '2018-01-10', 1, 100.00)
,(4, '2018-01-11', 1, 100.00)
,(5, '2018-01-12', 1, 100.00)
,(6, '2018-03-15', 1, 225.00)
,(7, '2018-03-15', 1, 25.00)
,(8, '2018-03-15', 1, 50.00)
,(9, '2018-04-20', 1, 100.00);
GO
DECLARE #Months int = 5; --number of historical months
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t100 AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1 AS num FROM t10 AS a CROSS JOIN t10 AS b)
, periods AS (SELECT
CONVERT(varchar(7), DATEADD(month, DATEDIFF(month, '', GETDATE()) - num, ''),121) AS Month
, DATEADD(month, DATEDIFF(month, '', CAST(GETDATE() AS date)) - num, '') AS PeriodStart
, DATEADD(month, DATEDIFF(month, '', CAST(GETDATE() AS date)) - num + 1, '') AS NextPeriodStart
FROM t100
WHERE num <= #Months
)
SELECT periods.Month, COALESCE(SUM(Amount), 0) AS TotalAmount, COALESCE(COUNT(ID), 0) AS TotalCount
FROM periods
LEFT JOIN dbo.TallyTable ON
TallyTable.Date >= PeriodStart
AND TallyTable.Date < NextPeriodStart
GROUP BY periods.Month
ORDER BY periods.Month;

Incorrect syntax near my alias when joining sub-queries?

My code is provided below. I get the error
"Incorrect syntax near the keyword 'otb'" (line 48)
and
"Incorrect syntax near the keyword 'otb_ly' "
I have no idea what this could mean! Because it makes sense to me to join my two sub-queries (that I've named otb and otb_ly).
On their own the sub-queries work just fine.
declare #snapLY table (hotel_id tinyint, import_date date)
insert into #snapLY select hotel_id, max(import_date) from [UKRMC].[dbo].[block_res]
where import_date <= convert(date, DATEADD(day, 1, DATEADD(year, -1, GETDATE()) ) )
group by hotel_id
select otb.sita,
otb.month_TY,
otb.year_TY,
otb.Market_segment,
otb.rn_TY as OTB_rn_TY,
otb.rev_TY as OTB_rev_TY
--otb_ly.rev_LY as OTB_rev_LY,
--otb_ly.rn_LY as OTB_rn_LY
(
select contacts.sita,
data.hotel_id,
data.month_TY
,data.year_TY
,Market_segment = seg.SEG
,rn_TY = ISNULL(datatwo.rn_TY,0)
,rev_TY = ISNULL(datatwo.rev_TY, 0)
from (
SELECT hotel_id, datename(month, DATEARRIVED) as month_TY, datename(year, DATEARRIVED) year_TY
FROM [UKRMC].[dbo].[revenue] rev
JOIN [UKRMC].[dbo].[contacts] contacts on rev.hotel_id = contacts.ID
WHERE DATEARRIVED BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101') -- first day of the month
AND DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))) -- 6 months later
and sita not like '%GLARR%'
group by hotel_id, datename(month, DATEARRIVED), datename(year, DATEARRIVED)
) data
cross join (
select SEG
from [UKRMC].[dbo].[Segmentation]
where SEG in ('RAC', 'BIT', 'BIQ', 'CBI', 'TOF', 'QOF', 'BAO', 'FIT', 'LYO', 'RER', 'OTH', 'NRG', 'XXX', 'CRW', 'BGR', 'BGO', 'LGR', 'LGS')
) seg
left join (
SELECT hotel_id, market_segment, datename(month, DATEARRIVED) month_TY, datename(year, DATEARRIVED) year_TY, sum(AMTROOM) as rev_TY, sum(STAYDAYS) as rn_TY
FROM [UKRMC].[dbo].[revenue] revtwo
WHERE DATEARRIVED BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101') -- first day of the month
AND DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))) -- 6 months later
AND hotel_id != 61 --not GLARR, id taken from contacts table
GROUP BY hotel_id, datename(month, DATEARRIVED), datename(year, DATEARRIVED), market_segment
) datatwo on data.hotel_id = datatwo.hotel_id and seg.SEG = datatwo.market_segment and data.month_TY = datatwo.month_TY and data.year_TY = datatwo.year_TY
join [UKRMC].[dbo].[contacts] contacts on contacts.id = data.hotel_id
) otb
LEFT JOIN
(
SELECT sita, market_seg, month_LY, year_LY, sum(rev_LY) as rev_LY, sum(rn_LY) as rn_LY
FROM (
SELECT block.hotel_id, SITA
,datename(month,stay_date) as month_LY
,datename(year, stay_date) as year_LY
,sum(rev_room) as rev_LY
,sum(quantity) as rn_LY
,market_seg
FROM [UKRMC].[dbo].[block_res] block
JOIN #snapLY spit on block.hotel_id = spit.hotel_id and block.import_date = spit.import_date
JOIN [UKRMC].[dbo].[Contacts] contacts on block.hotel_id = contacts.ID
WHERE stay_date >= DATEADD(year, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101'))
--stay_date >= DATEADD(year, -1, getdate())
and stay_date <= DATEADD(year, -1, DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))))
group by sita, market_seg, block.hotel_id, datename(month,stay_date),datename(year, stay_date)
UNION ALL
SELECT revenue.HOTEL_ID, SITA
,datename(month,DATEARRIVED) as month_LY
,datename(year,DATEARRIVED) as year_LY
,sum(AMTROOM) as rev_LY
,sum(STAYDAYS) as rn_LY
,market_segment
FROM [UKRMC].[dbo].[revenue] revenue
JOIN [UKRMC].[dbo].[Contacts] contacts on revenue.HOTEL_ID = contacts.ID
JOIN #snapLY spit on revenue.HOTEL_ID = spit.hotel_id
WHERE DATEARRIVED between DATEADD(year, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101'))
and DATEADD(day, -1, DATEADD(year, -1, getdate()))
and DATEARRIVED < spit.import_date
GROUP BY sita, revenue.HOTEL_ID, datename(month,DATEARRIVED), datename(year,DATEARRIVED), market_segment
) union_LY
GROUP BY sita, market_seg, hotel_id, month_LY, year_LY
) otb_ly
on otb.sita = otb_ly.sita and otb.Market_segment = otb_ly.market_seg and otb.month_LY = otb_ly.month_LY and otb.year_LY = otb_ly.year_LY
You're missing a FROM on Line 14:
...
--otb_ly.rn_LY as OTB_rn_LY
FROM
(
...
That query, in all honestly, needs a massive rework... That is really difficult to read.

SQL Server Group BY weekly clause blank if no data

No. 1 Query group by weekly
SELECT
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0) AS WeekStart,
SUM(Soil) AS TotalSoil,
SUM(Rock) AS TotalRock,
SUM(Concrete) AS TotalConcrete,
SUM(Steel) AS TotalSteel,
SUM(MovementPiles) AS TotalMovementPiles,
SUM(Total) AS OverallTotal
FROM
BplPjtRevenueStreams
WHERE
DailyDate > '2016-11-28 00:00:00.000'
AND DailyDate < '2016-12-05 00:00:00.000'
AND Project_Id = 5
GROUP BY
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0)
No. 2 query which have empty data in the table since table has no project_Id = 6 yet
SELECT
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0) AS WeekStart,
SUM(Soil) AS TotalSoil,
SUM(Rock) AS TotalRock,
SUM(Concrete) AS TotalConcrete,
SUM(Steel) AS TotalSteel,
SUM(MovementPiles) AS TotalMovementPiles,
SUM(Total) AS OverallTotal
FROM
BplPjtRevenueStreams
WHERE
DailyDate > '2016-11-28 00:00:00.000'
AND DailyDate < '2016-12-05 00:00:00.000'
AND Project_Id = 6
GROUP BY
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0)
May I know if I want to do something like this for the No. 2 query?
Week Start TotalSoil TotalRock TotalConcrete TotalSteel TotalMovementPiles OverallTotal
1 2016-11-28 00:00:00.000 NULL NULL NULL NULL NULL NULL
1 2016-12-05 00:00:00.000 NULL NULL NULL NULL NULL NULL
Is it possible to do like this if it's empty result in the table?
DECLARE
#Project_Id int = 6,
#RangeFrom datetime = '2016-11-28 00:00:00.000',
#RangeTo datetime = '2016-12-05 00:00:00.000'
;WITH Numbers AS
(
SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t(Value)
), Weeks AS
(
-- All weeks start from year 2000, Monday
SELECT DATEADD(WEEK, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), '1999-12-27') AS DateValue
FROM Numbers a CROSS JOIN Numbers b CROSS JOIN Numbers c CROSS JOIN Numbers d
), Data AS
(
-- This is your query
SELECT
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0) AS WeekStart,
SUM(Soil) AS TotalSoil,
SUM(Rock) AS TotalRock,
SUM(Concrete) AS TotalConcrete,
SUM(Steel) AS TotalSteel,
SUM(MovementPiles) AS TotalMovementPiles,
SUM(Total) AS OverallTotal
FROM
BplPjtRevenueStreams
WHERE
DailyDate > #RangeFrom
AND DailyDate < #RangeTo
AND Project_Id = #Project_Id
GROUP BY
DATEADD(week, DATEDIFF(week, 0, DailyDate), 0)
)
SELECT
CAST(w.DateValue AS datetime) AS WeekStart,
d.TotalSoil,
d.TotalRock,
d.TotalConcrete,
d.TotalSteel,
d.TotalMovementPiles,
d.OverallTotal
FROM Weeks w LEFT OUTER JOIN Data d ON w.DateValue = CAST(d.WeekStart AS date)
WHERE
w.DateValue BETWEEN CAST(#RangeFrom AS date) AND CAST(#RangeTo AS date)

How to union two cte statements in sql with declare ERROR :Incorrect syntax near the keyword 'DECLARE'

I am using CTE for union two columns in sql.
If I am executing these two queries it is working fine .
But I want to make union of these two for more simpler O/P.
I am getting compile time error :
Incorrect syntax near the keyword 'DECLARE'.
can anyone tell me hoe to achieve union with cte
DECLARE #Inward DATETIME
SET #Inward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
WITH cte AS
(
SELECT 0 AS TheMonth
UNION ALL
SELECT TheMonth + 1
FROM cte
WHERE TheMonth < 5
)
SELECT
cte.TheMonth,
isnull(sum(qty),0) as inward
FROM
cte
LEFT OUTER JOIN RS_GIN_Master as g
ON accept_date >= DATEADD(MM, cte.TheMonth, #Inward) AND accept_date < DATEADD(MM, cte.TheMonth + 1, #Inward)
UNION all
DECLARE #Outward DATETIME
SET #Outward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
WITH cte AS
(
SELECT 0 AS TheMonthO
UNION ALL
SELECT TheMonthO + 1
FROM cte
WHERE TheMonthO < 5
)
SELECT isnull(sum(quantity),0) as outward
FROM
cte
LEFT OUTER JOIN
RS_Sell_Order_Master as s
ON del_date >= DATEADD(MM, cte.TheMonthO, #Outward) AND del_date < DATEADD(MM, cte.TheMonthO + 1, #Outward) and isDelivered = 1
left outer join RS_Sell_Order_Mapping as sm on sm.sell_order_no = s.sell_order_no
Where to begin.
You cannot use declare statements inside of union statements.
Union statements must return the same number of columns.
Common table expressions should only be defined at the beginning of your statement.
Your Sum aggregate needs a group by to return each month.
Perhaps you're looking for something like this:
DECLARE #Inward DATETIME
DECLARE #Outward DATETIME
SET #Inward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
SET #Outward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
WITH cte AS
(
SELECT 0 AS TheMonth
UNION ALL
SELECT TheMonth + 1
FROM cte
WHERE TheMonth < 5
)
SELECT
cte.TheMonth,
isnull(sum(qty),0) as inward,
null as outward
FROM
cte
LEFT OUTER JOIN RS_GIN_Master as g
ON accept_date >= DATEADD(MM, cte.TheMonth, #Inward)
AND accept_date < DATEADD(MM, cte.TheMonth + 1, #Inward)
GROUP BY cte.TheMonth
UNION all
SELECT
cte.TheMonth,
null as inward,
isnull(sum(quantity),0) as outward
FROM
cte
LEFT OUTER JOIN RS_Sell_Order_Master as s
ON del_date >= DATEADD(MM, cte.TheMonthO, #Outward)
AND del_date < DATEADD(MM, cte.TheMonthO + 1, #Outward) and isDelivered = 1
left outer join RS_Sell_Order_Mapping as sm on
sm.sell_order_no = s.sell_order_no
GROUP BY cte.TheMonth
Ha! I'm looked it today because i had the same question. You must declare the first CTE with the "WITH" Keyword and every CTE you need, just separate it with a comma.
EDIT from sgeedes Query above
DECLARE #Inward DATETIME
DECLARE #Outward DATETIME
SET #Inward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
SET #Outward = DATEADD(mm, -6, CURRENT_TIMESTAMP);
WITH cte AS
(
SELECT 0 AS TheMonth
UNION ALL
SELECT TheMonth + 1
FROM cte
WHERE TheMonth < 5
)
SELECT TheMonth,sum(Inward) as InWard, sum(OutWard) as OutWard
FROM
(
SELECT
cte.TheMonth,
isnull(sum(qty),0) as inward,
0 as outward
FROM
cte
LEFT OUTER JOIN RS_GIN_Master as g
ON accept_date >= DATEADD(MM, cte.TheMonth, #Inward)
AND accept_date < DATEADD(MM, cte.TheMonth + 1, #Inward)
GROUP BY cte.TheMonth
UNION all
SELECT
cte.TheMonth,
0 as inward,
isnull(sum(quantity),0) as outward
FROM
cte
LEFT OUTER JOIN RS_Sell_Order_Master as s
ON del_date >= DATEADD(MM, cte.TheMonthO, #Outward)
AND del_date < DATEADD(MM, cte.TheMonthO + 1, #Outward) and isDelivered = 1
left outer join RS_Sell_Order_Mapping as sm on
sm.sell_order_no = s.sell_order_no
GROUP BY cte.TheMonth
)Z