here is my query and result;
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
SUM(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores on Stores.ID = StoreRevenue.StoreID
group by DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0), Stores.Name
result : http://prntscr.com/zaele
I want to create a table (result) that must be group by date and store names.
Date, Avcılar Mağaza, Ataşehir Mağaza
2013-03-04, 150, 200
2013-03-05, 200, 250
2013-03-06, 300, 150
rows of sub-group (these ones: 2013-03-04, 150, 200) are date and incomes of each stores
I want to get that kind of result
I have also tried "pivot" in sql but It doesnt work for me
sorry for my english. -Thanks
You can use the PIVOT function to transform the data from rows to columns:
select *
from
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
) d
pivot
(
sum(Revenue)
for StoreName in ([Avcılar Mağaza], [Ataşehir Mağaza]..)
) piv;
Or you can use an aggregate function with a CASE:
select DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
sum(case when Stores.Name = 'Avcılar Mağaza'
then PosCash + PosCredit + PosBillCash + PosBillCredit end) as [Avcılar Mağaza],
sum(case when Stores.Name = 'Ataşehir Mağaza'
then PosCash + PosCredit + PosBillCash + PosBillCredit end) as [Ataşehir Mağaza]
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
group by DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0)
If you have an unknown number fo stores, then you can use dynamic sql:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(name)
from Stores
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Date, ' + #cols + '
from
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
(PosCash + PosCredit + PosBillCash + PosBillCredit) as Revenue
from StoreRevenue
inner join Stores
on Stores.ID = StoreRevenue.StoreID
) x
pivot
(
sum(Revenue)
for StoreName in (' + #cols + ')
) p '
execute(#query)
Try this:
WITH CTE
AS
(
select
DATEADD(dd, DATEDIFF(dd, 0, PostDate), 0) as Date,
Stores.Name StoreName,
PosCash + PosCredit + PosBillCash + PosBillCredit as Revenue
from StoreRevenue
inner join Stores on Stores.ID = StoreRevenue.StoreID
)
SELECT *
FROM CTE AS c
PIVOT
(
SUM(Revenue)
FOR StoreName IN ([Avcılar Mağaza], [Ataşehir Mağaza], ...)
) AS p
Related
There are 3 tables -
Attendance (EnrollmentNo,SubjectCode,Date,Attendance)
Student (EnrollmentNo, RollNo),
UserDetails(EnrollmentNo,FirstName,LastName).
Now what I want is to display the attendance month-wise taking Roll No, Name, dates as column and Student.RollNo, UserDetails.FirstName, UserDetails.LastName, Attendance.Attendance as the data for the columns respectively.
But the problem I am facing is how to generate date columns dynamically and put the attendance data in the respective date column.
Input - Startdate and Enddate
Expected Output -
-------------------------------------------------------
| Roll No | Name | 01-09-2018 | 01-12-2018|
-------------------------------------------------------
| 15 | Suyash Gupta | 1 | 0 |
-------------------------------------------------------
| 24 | Himanshu Shukla | 2 | 2 |
-------------------------------------------------------
| 32 | Dhruv Raj Sirohi | 1 | 1 |
-------------------------------------------------------
This is my approach -
DECLARE #startdate date
DECLARE #enddate date
SET #startdate = convert(date,'01-09-2018')
SET #enddate = convert(date,'01-12-2018')
;with cte (#startdate, #enddate) as /*I don't know how to pass my date range
in cte() as this takes table column*/
(
select 1
union all
select dateadd(dd, 1, startdate)
from cte
where startdate <= enddate
)
select c.startdate
into #tempDates
from cte c
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10),
startdate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT RollNo,FirstName,LastName, ' + #cols + ' from
(
select S.RollNo,U.FirstName,U.LastName,
D.startdate,
convert(CHAR(10), startdate, 120) PivotDate
from #tempDates D
left join Attendance A
on D.startdate = A.Date
) x
pivot
(
count(startdate)
for PivotDate in (' + #cols + ')
) p '
execute(#query)
you have some issues with your code, look at the differences in my code:
DECLARE #startdate date = '20180109';
DECLARE #enddate date = '20180112';
DECLARE #cols as varchar(2000);
DECLARE #query as varchar(MAX);
WITH cte (startdate)
AS
(SELECT
#startdate AS startdate
UNION ALL
SELECT
DATEADD(DAY, 1, startdate) AS startdate
FROM cte
WHERE startdate < #enddate)
SELECT
#cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(CONVERT(CHAR(10),
startdate, 120))
FROM cte
FOR XML PATH (''), TYPE)
.value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
SET #query = 'SELECT RollNo,FirstName,LastName, ' + #cols + ' from
(
select S.RollNo,U.FirstName,U.LastName,
D.startdate,
convert(CHAR(10), startdate, 120) PivotDate
from #tempDates D
left join Attendance A
on D.startdate = A.Date
) x
pivot
(
count(startdate)
for PivotDate in (' + #cols + ')
) p '
EXECUTE (#query)
Do you mean something like this:
DECLARE #StartDate AS DATETIME, #EndDate AS DATETIME
SET #StartDate='2018-01-01'
SET #EndDate='2018-01-10'
SELECT Student.RollNo, Student.FirstName, Student.LastName, Attendance.Date
FROM Attendance,Student,UserDetails
WHERE Attendance.EnrollmentNo=Student.EnrollmentNo
AND UserDetails.EnrollmentNo=Student.EnrollmentNo
AND Attendance.[Date] between #StartDate and #EndDate
UPDATE
Based on what you said in the question maybe the following code is what you need:
SELECT Student.RollNo, Student.FirstName, Student.LastName,
STUFF((SELECT ','+CAST([DATE] AS VARCHAR(30))
FROM Attendance
WHERE Attendance.EnrollmentNo=Student.EnrollmentNo
AND Attendance.[Date] between #StartDate AND #EndDate
FOR XML PATH('')
), 1, 1, '') Dates
FROM Student,UserDetails
WHERE UserDetails.EnrollmentNo=Student.EnrollmentNo
This is running code and giving me the desired output. I want to thank Lobo, who corrected me, and everyone else who had put in the efforts to help me. Thank you all and stackoverflow who provided me the platform to query the problem I was facing.
DECLARE #startdate date = '20180109';
DECLARE #enddate date = '20180112';
DECLARE #cols as varchar(2000);
DECLARE #query as varchar(MAX);
WITH cte (startdate)
AS
(SELECT
#startdate AS startdate
UNION ALL
SELECT
DATEADD(DAY, 1, startdate) AS startdate
FROM cte
WHERE startdate < #enddate
)
select c.startdate
into #tempDates
from cte c
SELECT
#cols = STUFF((SELECT DISTINCT
',' + QUOTENAME(CONVERT(CHAR(10),
startdate, 120))
FROM #tempDates
FOR XML PATH (''), TYPE)
.value('.', 'NVARCHAR(MAX)')
, 1, 1, '')
SET #query = 'SELECT RollNo,FirstName,LastName, ' + #cols + ' from
(
select S.RollNo,U.FirstName,U.LastName,
D.startdate,
convert(CHAR(10), startdate, 120) PivotDate
from #tempDates D,Attendance A, Student S, UserDetails U
where D.startdate = A.Date and A.EnrollmentNo=S.EnrollmentNo and A.EnrollmentNo=U.userID
) x
pivot
(
count(startdate)
for PivotDate in (' + #cols + ')
) p '
EXECUTE (#query)
drop table #tempDates
I have been displaying Day Wise Attendance Data with Pivot SQL.
declare #startdate datetime = '2016-09-26'
declare #enddate datetime = '2016-10-01'
declare #CompanyID int = 1
DECLARE #COLUMN VARCHAR(MAX), #SQL NVARCHAR(MAX);
SET #COLUMN = N'';
DECLARE #DATERANGE TABLE (DateToCheck DATE)
;WITH Temp
AS
(
SELECT DT =DATEADD(DD,0, #startdate)
WHERE DATEADD(DD, 1, #startdate) <= #enddate
UNION ALL
SELECT DATEADD(DD, 1, DT)
FROM Temp
WHERE DATEADD(DD, 1, DT) <= #enddate
)
INSERT INTO #DATERANGE
SELECT DT From Temp
SELECT #COLUMN += N', T.' + QUOTENAME(DateRanges) FROM (SELECT CAST(CONVERT(DATE, T.DateToCheck) AS VARCHAR(10)) AS DateRanges FROM #DATERANGE T group by T.DateToCheck) AS A;
SET #SQL = '
DECLARE #DATERANGE TABLE (DateToCheck DATE)
;WITH Temp
AS
(
SELECT DT =DATEADD(DD,0, #startdate)
WHERE DATEADD(DD, 1, #startdate) <= #enddate
UNION ALL
SELECT DATEADD(DD, 1, DT)
FROM Temp
WHERE DATEADD(DD, 1, DT) <= #enddate
)
INSERT INTO #DATERANGE
SELECT DT From Temp
SELECT *
FROM (
SELECT E.FirstName, E.LastName, E.Email, T.DateToCheck, COALESCE(A.val, L.val, H.val, ''Absent'') val
FROM AspNetUsers E
CROSS APPLY (
SELECT DateToCheck FROM #DATERANGE
) T--(DateToCheck)
LEFT JOIN (SELECT ''Holiday'' val, HolidayDate, CompanyID FROM Holidays) H ON H.HolidayDate = T.DateToCheck AND H.CompanyID = #CompanyID
LEFT JOIN (SELECT ''In : '' + CONVERT(VARCHAR, MIN(AttendanceDateTime), 108) + '' / Out : '' + CONVERT(VARCHAR, MAX(AttendanceDateTime), 108) val, CAST(AttendanceDateTime As DATE) As AttendanceDate, UserID FROM Attendances GROUP BY CAST(AttendanceDateTime As DATE), UserID) A ON A.AttendanceDate = T.DateToCheck AND A.UserID = E.Id
LEFT JOIN (SELECT ''Leave'' val, LeaveDate, UserID FROM LeaveApplications) L ON L.LeaveDate = T.DateToCheck AND L.UserID = E.Id
WHERE E.CompanyID = #CompanyID
) T
PIVOT (MAX(val) FOR DateToCheck IN (' + STUFF(REPLACE(#COLUMN, ', T.[', ',['), 1, 1, '') + ')) P';
EXEC sp_executesql #SQL, N'#startdate DATE, #enddate DATE, #CompanyID INT', #startdate, #enddate, #CompanyID
And below is the result set of how it's now
Now I wish to add more field to the above SQL to display counts like PresentCount, AbsentCount, HolidayCount and LeaveCount
I have already written a SQL where I could easily display these counts but, I'm unable to make it work with the above PIVOT SQL.
So in this case, the result for first row would be PresentCount = 0, AbsentCount = 6, HolidayCount = 0 and LeaveCount = 0. For Row 2 it would be PresentCount = 4, AbsentCount = 2, LeaveCount and HolidayCount both is 0.
I have this query segment below where I'm trying to build a string of "month-year" from a date field in this table. It's very important that it comes in the right order starting from current month going forward 12 months.
DECLARE #cols AS NVARCHAR(MAX)
SELECT #cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y
FROM Products2
) AS Y
--ORDER BY y desc
FOR XML PATH('')),
1, 1, N'')
This query isn't pulling the dates in the right order and I wanted to see if you guys know of any neat tricks to pull the dates in the correct order. I can bring in the startDate column and sort it by that but it brings in duplicates as it may have several entries for the same month. I've created a sample table here http://sqlfiddle.com/#!6/3a500/5
You could use
DECLARE #cols AS NVARCHAR(MAX);
SELECT #cols = STUFF((SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2) AS y,
MIN(StartDate) AS z
FROM Products2
GROUP BY CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2)) AS Y
ORDER BY z
FOR XML PATH('')), 1, 1, N'');
SELECT #cols;
SQL Fiddle
It looks like you just getting the month/year so we can truncate to the first day of the month and include that in the query.
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
Now we can order by it:
DECLARE #cols AS NVARCHAR(MAX);
SELECT #cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (
SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y,
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select #cols;
This is the output:
[Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16]
Is that what you are looking for? Here is a fiddle:
http://sqlfiddle.com/#!6/3a500/67
Better yet, just select the distinct month start dates and then only do the string conversion on that.
DECLARE #cols AS NVARCHAR(MAX);
SELECT #cols = STUFF(
(SELECT N',' + QUOTENAME(CONVERT(char(3), monthStart, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(monthStart)), 2)) AS [text()]
FROM (
SELECT DISTINCT
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select #cols;
Here is that fiddle:
http://sqlfiddle.com/#!6/3a500/72
If you are using SQL Server 2012+ you could use FORMAT function:
DECLARE #cols AS NVARCHAR(MAX);
;WITH cte AS -- get only one date per month/year
(
SELECT MIN(StartDate) AS StartDate
FROM #Products2
GROUP BY YEAR(StartDate),MONTH(StartDate)
)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(FORMAT(StartDate, 'MMM-yy'))
FROM cte
ORDER BY StartDate
FOR XML PATH('')),
1, 1, N'');
SELECT #cols;
LiveDemo
Output:
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ result ║
╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ [Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16] ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
I have the query which returning me the number of categories in one cloumn and other column are dynamic column they are giving me the the months between start date & end date and this column are returning me the amount of the categories sold on that month.
I want to add the Grand Total at the end of the row in the query
Here's My Query
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#subtotal AS FLOAT,
#startdate as datetime,
#enddate as datetime
DECLARE #ColumnsRollup AS VARCHAR (MAX)
set #startdate = '1-Mar-2014'
set #enddate = '1-Aug-2014'
;with cte (StartDate, EndDate) as
(
select min(#startdate) StartDate, max(#enddate) EndDate
union all
select dateadd(mm, 1, StartDate), EndDate
from cte
where StartDate < EndDate
)
select StartDate
into #tempDates
from cte
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), StartDate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') + ',[Total]'
SET #query = 'select ledger_name,
' + #cols + '
from
(
SELECT
CASE WHEN (GROUPING(ledger_name) = 1) THEN ''Grand Total''
ELSE ledger_name END AS ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by
ledger_name,StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
ORDER BY CASE WHEN ledger_name = ''Grand Total'' THEN 1 END'
execute sp_executesql #query;
drop table #tempDates
I think what you can do is, try to use the ROLLUP option in your inner query, which actually returns addtional row for the SUM(Amount), which you can call as Total and add this column to your column list.
Here is the change what I think you need to do
Add total column at the end of your column list
SET #cols= #cols + ',[Total]'
Add the rollup option to your inner query. Note that, the case statement is required to change the text as total for the row.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#subtotal AS FLOAT,
#startdate as datetime,
#enddate as datetime
DECLARE #ColumnsRollup AS VARCHAR (MAX)
set #startdate = '1-Mar-2014'
set #enddate = '1-Aug-2014'
;with cte (StartDate, EndDate) as
(
select min(#startdate) StartDate, max(#enddate) EndDate
union all
select dateadd(mm, 1, StartDate), EndDate
from cte
where StartDate < EndDate
)
select StartDate
into #tempDates
from cte
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), StartDate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') + ',[Total]'
SET #query = 'select ledger_name,
' + #cols + '
from
(
SELECT
ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by
ledger_name,StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
WHERE ledger_name IS NOT NULL
UNION ALL
select ledger_name,
' + #cols + ' FROM
(SELECT ''Grand Total'' AS ledger_name,
ISNULL(SUM(amount),0) Amount,
CASE WHEN (GROUPING(StartDate) = 1) THEN ''Total''
ELSE convert(CHAR(10), StartDate, 120) END StartDate
FROM #tempDates d
left join Rs_Ledger_Master AS LM on d.StartDate between '''+convert(varchar(10), #startdate, 120)+''' and '''+convert(varchar(10), #enddate, 120)+'''
LEFT OUTER JOIN RS_Payment_Master AS PM ON PM.ledger_code = LM.ledger_code and month(paid_date) = month(StartDate) and year(paid_date) = year(StartDate)
group by StartDate WITH ROLLUP
) d
pivot
(
SUM(Amount)
for StartDate in (' + #cols + ')
) p
'
print #query
execute sp_executesql #query;
drop table #tempDates
You need additional union all to get the last summary row
You can refer the following article for using ROLLUP
http://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx
I am sorry that there are lots of questions on this already on the stack overflow.
But They did not solved my issue regarding to the null value.
I want to eliminate Null value from the output.
I have already used below technique for my query but still problem is not solved.
SET ANSI_WARNINGS OFF;**
SUM(CASE WHEN [qty] IS NULL THEN 0 ELSE qty END) AS [qty]
Here's my query
SET ANSI_WARNINGS ON;
DECLARE #cols nvarchar(max),
#query nvarchar(max),
#Date DATETIME
SET #Date = DATEADD(mm, -6, CURRENT_TIMESTAMP);
WITH cte AS
(
SELECT 0 AS TheMonth
UNION ALL
SELECT TheMonth + 1
FROM cte
WHERE TheMonth < 5
)
SELECT TheMonth
INTO #temp
FROM cte
SELECT #cols = STUFF((SELECT distinct ',' + QUOTENAME(A.warehouse_name)
from RS_Company_Warehouse_Master a
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET ANSI_WARNINGS OFF;
SELECT #query = 'SELECT
LEFT(DATENAME(MONTH,DATEADD(MONTH,TheMonth -6 + 1,GETDATE())),3) AS [month],
DATEPART(YEAR,DATEADD(MONTH,TheMonth - 6 + 1 ,GETDATE())) AS [year],
'+#cols+'
from
(
SELECT
TheMonth,
SUM(CASE WHEN [qty] IS NULL THEN 0 ELSE qty END) AS [qty],
warehouse_name
FROM
#temp
LEFT OUTER JOIN RS_Sell_Order_Master AS SM ON invoice_date >= DATEADD(MM, TheMonth, '''+convert(varchar(10), #Date, 120)+''')
AND invoice_date < DATEADD(MM, TheMonth + 1, '''+convert(varchar(10), #Date, 120)+''')
LEFT OUTER JOIN RS_Company_Warehouse_Master AS CWM ON CWM.c_warehouse_id = SM.c_warehouse_id
LEFT OUTER JOIN RS_Sells_Invoice_Info_Master AS SIIM ON SIIM.sell_order_no = SM.sell_order_no
GROUP BY
CWM.warehouse_name,
TheMonth
) as a
PIVOT
(
sum(qty) for warehouse_name
IN ('+#cols+')
) AS P
'
execute sp_executesql #query;
DROP TABLE #temp
Output:
Create two #cols list. In one Add is null check in the final Pivot columns as:
DECLARE #colsFinal nvarchar(max)
SET #colsFinal = N''
SELECT #colsFinal = STUFF((SELECT distinct ',' +
'ISNULL ( ''' + QUOTENAME(A.warehouse_name) +''', 0) as '
+ QUOTENAME(A.warehouse_name)
from RS_Company_Warehouse_Master a
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
and change your main query as:
SELECT #query = 'SELECT
LEFT(DATENAME(MONTH,DATEADD(MONTH,TheMonth -6 + 1,GETDATE())),3) AS [month],
DATEPART(YEAR,DATEADD(MONTH,TheMonth - 6 + 1 ,GETDATE())) AS [year],
'+#colsFinal+'
from
(
SELECT
TheMonth,
SUM(CASE WHEN [qty] IS NULL THEN 0 ELSE qty END) AS [qty],
warehouse_name
FROM
#temp
LEFT OUTER JOIN RS_Sell_Order_Master AS SM ON invoice_date
>= DATEADD(MM, TheMonth, '''+convert(varchar(10), #Date, 120)+''')
AND invoice_date < DATEADD(MM, TheMonth + 1, '''
+convert(varchar(10), #Date, 120)+''')
LEFT OUTER JOIN RS_Company_Warehouse_Master AS CWM ON CWM.c_warehouse_id = SM.c_warehouse_id
LEFT OUTER JOIN RS_Sells_Invoice_Info_Master AS SIIM ON SIIM.sell_order_no = SM.sell_order_no
GROUP BY
CWM.warehouse_name,
TheMonth
) as a
PIVOT
(
sum(qty) for warehouse_name
IN ('+#cols+')
) AS P
'
SQL Fiddle Demo Here