How to insert a TOTAL column in this SQL Pivot query? - sql

I have a SQL Pivot query which works fine. However, I need to add a TOTAL column in the output (which will be the SUM of all the months).
My query (extract) stands as follows:
...
SELECT [Year],[Property], ISNULL([Jan],0) as [Jan], ISNULL([Feb],0) as [Feb], ISNULL([Mar],0) as [Mar], ISNULL([Apr],0) as [Apr], ISNULL([May],0) as [May], ISNULL([Jun],0) as [Jun],
ISNULL([Jul],0) as [Jul], ISNULL([Aug],0) as [Aug], ISNULL([Sep],0) as [Sep], ISNULL([Oct],0) as [Oct], ISNULL([Nov],0) as [Nov], ISNULL([Dec],0) as [Dec]
FROM (
SELECT [MthName], [Year], [RN], [Property] from CTE1
UNION ALL
SELECT [MthName], [Year], [RN], [Property] from CTE2
)x
PIVOT(SUM(x.[RN])
FOR x.[MthName] IN ([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])) AS PVTTable
ORDER BY [Property], [Year] DESC
An extract of the output of this query is shown below:
Year Property Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2018 XYZ 3261 2955 3045 2118 1917 869 1772 1598 834 1254 537 415
2017 XYZ ...
I need to add a 'Total' column at the end of this output. How can I do this?

Add this part at the last in your Select query:
(ISNULL([Jan],0)+ ISNULL([Feb],0) + ISNULL([Mar],0)+ ISNULL([Apr],0)+ ISNULL([May],0)+ ISNULL([Jun],0) + ISNULL([Jul],0)+ ISNULL([Aug],0)+ ISNULL([Sep],0)+ ISNULL([Oct],0) + ISNULL([Nov],0)+ ISNULL([Dec],0)) as [Total]

I would use conditional aggregation approach instead of using cte with PIVOT operation
select Year,
Property,
SUM(case when MthName = 'Jan' then RN else 0 end) Jan,
SUM(case when MthName = 'Feb' then RN else 0 end) Feb,
SUM(case when MthName = 'Mar' then RN else 0 end) Mar,
...
SUM(RN) Total
from table t
group by year, Property

Related

How to replace NULL with zero in the output of this pivot query? [duplicate]

This question already has answers here:
How to replace (null) values with 0 output in PIVOT
(7 answers)
Closed 5 years ago.
I am using SQL Server 2012 and I have the following SQL query:
SELECT *
FROM
(SELECT [Mth], [Year], [Amount], [Market]
FROM CTE1
UNION ALL
SELECT [Mth], [Year], [Amount], [Market]
FROM CTE2) x
PIVOT
(SUM(x.[Amount)
FOR x.[Mth] IN ([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])
) AS PVTTable
Extract of output is as follows:
Year Market Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2017 France 11 20 NULL 16 NULL 8 NULL NULL NULL NULL 5 9
I want to replace the NULL with zero. I have tried ISNULL([Mth],0) in my SELECT queries but it's not working.
It's SUM(x.[Amount]) that has the value NULL here, not [mth]. I'm not sure you can, however, use an ISNULL in the PIVOT (no Sample data with which to actually check (and I tend to use do a cross pivot, rather than using PIVOT). If you can't you'll need to put the ISNULL in your outer SELECT statemeent:
SELECT [Year], Market,
ISNULL(Jan,0) AS Jan,
ISNULL(Feb,0) AS Feb, ...

SQL Pivot Table from query

How can I convert this query to pivot
select
branch,
months,
[Parts Revenue Budget]
from #Temp1
Result
Desired Output
You can use conditional aggregation :
SELECT t.branch,
SUM(CASE WHEN t.months = 'JAN' THEN t.[Parts Revenue Budget] ELSE 0 END) as JAN,
SUM(CASE WHEN t.months = 'FEB,' THEN t.[Parts Revenue Budget] ELSE 0 END) as FEB
... As many as you need
SUM(t.[Parts Revenue Budget]) as grandtotal
FROM #Temp1
GROUP BY t.branch
UNION ALL
SELECT 'Grand Total',
SUM(CASE WHEN t.months = 'JAN' THEN t.[Parts Revenue Budget] ELSE 0 END) as JAN,
SUM(CASE WHEN t.months = 'FEB' THEN t.[Parts Revenue Budget] ELSE 0 END) as FEB,
... As many as you need
SUM(t.[Parts Revenue Budget]) as grandtotal
FROM #Temp1 t
SELECT BRANCH,
SUM(CASE WHEN MONTHS = 'JAN' THEN PARTSREVENUEBUDJET END) AS [JAN],
SUM(CASE WHEN MONTHS = 'FEB' THEN PARTSREVENUEBUDJET END) AS [FEB],
SUM(CASE WHEN MONTHS = 'MAR' THEN PARTSREVENUEBUDJET END) AS [MARCH],
SUM(CASE WHEN MONTHS = 'APR' THEN PARTSREVENUEBUDJET END) AS [APR],
SUM(CASE WHEN PONITS = 'MAY' THEN PARTSREVENUEBUDJET END) AS [MAY],
SUM(CASE WHEN MONTHS = 'JUNE' THEN PARTSREVENUEBUDJET END) AS [JUNE],
SUM(CASE WHEN MONTHS = 'JULY' THEN PARTSREVENUEBUDJET END) AS [JULY],
SUM(CASE WHEN MONTHS = 'AUG' THEN PARTSREVENUEBUDJET END) AS [AUG],
SUM(CASE WHEN MONTHS = 'SEP' THEN PARTSREVENUEBUDJET END) AS [SEP],
SUM(CASE WHEN MONTHS = 'OCT' THEN PARTSREVENUEBUDJET END) AS [OCT],
SUM(CASE WHEN MONTHS = 'NOV' THEN PARTSREVENUEBUDJET END) AS [NOV],
SUM(CASE WHEN MONTHS = 'NOV' THEN PARTSREVENUEBUDJET END) AS [DEC],
SUM(PARTSREVENUEBUDJET) AS 'GRANDTOTAL'
FROM TABLE
GROUP BY BRANCH
2)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(months)
from #TEMP1
group by months
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT branch,' + #cols + ',tiot from
(
select *,sum(BUDGET)over(partition by branch) as tiot
from #TEMP1
) x
pivot
(
sum(BUDGET)
for months in (' + #cols + ')
) p '
exec(#query);
I tried as follows:
CREATE TABLE #TEMP1(BRANCH VARCHAR(100),MONTHS VARCHAR(100),BUDGET varchar(100))
INSERT INTO #TEMP1 VALUES ('CPD','APR','801375')
INSERT INTO #TEMP1 VALUES ('Sabzi Mandi','APR','1033697')
INSERT INTO #TEMP1 VALUES ('DHA','APR','2119835')
INSERT INTO #TEMP1 VALUES ('Quidabad','APR','2100042')
INSERT INTO #TEMP1 VALUES ('Sukkar','AUG','44377320')
INSERT INTO #TEMP1 VALUES ('Baghbanpura','AUG','2726114')
INSERT INTO #TEMP1 VALUES ('Multan','AUG','6068565')
select *,coalesce(CAST(AUG AS NUMERIC(10,2)),0)+coalesce(CAST(apr AS NUMERIC(10,2)),0) as 'grand total'
from
(select branch , months ,budget from #temp1) as s
pivot
(MAX(BUDGET) for months in (APR,AUG)) AS PVT
CREATE TABLE TEMP1(BRANCH VARCHAR(100),MONTHS VARCHAR(100),BUDGET FLOAT(126));
INSERT INTO TEMP1 VALUES ('ABC','AUG','1000');
INSERT INTO TEMP1 VALUES ('PQR','APR','2000');
INSERT INTO TEMP1 VALUES ('XYZ','AUG','1000');
SELECT
BRANCH,
APR,
AUG,
(NVL(APR,'0')+NVL(AUG,'0')) AS GRANDTOTAL
FROM
(SELECT
*
FROM
(
SELECT
BRANCH,
MONTHS,
BUDGET
FROM
TEMP1
)
pivot ( MIN(BUDGET) FOR MONTHS IN ('APR' AS APR,'AUG' AS AUG)))
UNION ALL
SELECT 'GRAND TOTAL' AS BRANCH,SUM(APR) AS APR, SUM(AUG) AS AUG, SUM(GRANDTOTAL) AS GRANDTOTAL
FROM
(SELECT
BRANCH,
APR,
AUG,
(NVL(APR,'0')+NVL(AUG,'0')) AS GRANDTOTAL
FROM
(SELECT
*
FROM
(
SELECT
BRANCH,
MONTHS,
BUDGET
FROM
TEMP1
)
pivot ( MIN(BUDGET) FOR MONTHS IN ('APR' AS APR,'AUG' AS AUG) )));

SQL Server Pivot Row Total

I'm using SQL Server 2012 and have the below pivot code that works fine. However, how do I include a row total i.e. a sum of the recorded amount for each account over the course of the year?
SELECT *
FROM (
SELECT [Account],[AccountDesc], CONVERT(CHAR(4), AccDate, 100) as [Month], [RecordedAmount]
FROM [tblGLS215_2016_2017]
WHERE [Employee] = #Employee
) AS s
PIVOT
(
SUM ([RecordedAmount])
FOR [Month] in (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sept, Oct, Nov, Dec)
) As pvt
Any help would be greatly appreciated.
If anyone is interested this is the final working solution:
SELECT pvt.* ,Isnull(pvt.jan,0) +Isnull(pvt.feb,0) +Isnull(pvt.mar,0) +Isnull(pvt.apr,0) +Isnull(pvt.may,0) +Isnull(pvt.jun,0) +Isnull(pvt.jul,0) +Isnull(pvt.aug,0) +Isnull(pvt.sept,0) +Isnull(pvt.oct,0) +Isnull(pvt.nov,0) as YearTotal
FROM (
SELECT [Account],[AccountDesc], CONVERT(CHAR(4), AccDate, 100) as [Month], [RecordedAmount]
FROM [tblGLS215_2016_2017]
WHERE [Employee] = #Employee
) AS s
pivot (
SUM ([RecordedAmount])
FOR [Month] in (May, Jun, Jul, Aug, Sept, Oct, Nov, Dec, Jan, Feb, Mar, Apr)
) As pvt
this would also work for you and might perform better
SELECT [Account],
[AccountDesc],
SUM(CASE WHEN [Month] = 'Jan' THEN [RecordedAmount] END) AS [Jan],
SUM(CASE WHEN [Month] = 'Feb' THEN [RecordedAmount] END) AS [Feb],
SUM(CASE WHEN [Month] = 'Mar' THEN [RecordedAmount] END) AS [Mar],
SUM(CASE WHEN [Month] = 'Apr' THEN [RecordedAmount] END) AS [Apr],
SUM(CASE WHEN [Month] = 'May' THEN [RecordedAmount] END) AS [May],
SUM(CASE WHEN [Month] = 'Jun' THEN [RecordedAmount] END) AS [Jun],
SUM(CASE WHEN [Month] = 'Jul' THEN [RecordedAmount] END) AS [Jul],
SUM(CASE WHEN [Month] = 'Aug' THEN [RecordedAmount] END) AS [Aug],
SUM(CASE WHEN [Month] = 'Sept' THEN [RecordedAmount] END) AS [Sept],
SUM(CASE WHEN [Month] = 'Oct' THEN [RecordedAmount] END) AS [Oct],
SUM(CASE WHEN [Month] = 'Nov' THEN [RecordedAmount] END) AS [Nov],
SUM(CASE WHEN [Month] = 'Dec' THEN [RecordedAmount] END) AS [Dec],
SUM([RecordedAmount]) AS [Total]
FROM (
SELECT [Account],
[AccountDesc],
CONVERT(CHAR(4),AccDate,100) AS [Month],
[RecordedAmount]
FROM [tblGLS215_2016_2017]
WHERE [Employee] = #Employee
) t
GROUP BY [Account],
[AccountDesc]
works the same as pivot but gives a little more control when including extra information.

How to use pivot and have 2 different aggregate functions?

I have a table with 1 date column. I want to group the dates by year and month so that I have a matrix such as:
Year Jan Feb Mar...Dec Total
2015.....
2016 10 15 10... 10 115
2017.....
Is this possible to achieve using the PIVOT function, and how exactly do I use it to achieve the above?
You can achieve without PIVOT
SELECT
DATEPART(yyyy,t.the_date) as year,
SUM(CASE WHEN DATEPART(mm,t.the_date)=1 THEN 1 ELSE 0 END) as Jan,
SUM(CASE WHEN DATEPART(mm,t.the_date)=2 THEN 1 ELSE 0 END) as Feb,
...
SUM(CASE WHEN DATEPART(mm,t.the_date)=12 THEN 1 ELSE 0 END) as Dec,
COUNT(*) as Total
FROM the_table t
GROUP BY DATEPART(yyyy,t.the_date)
try using this query : -
SELECT *
FROM (
SELECT
year(yourDate) as [year],left(datename(month,yourDate),3)as [month],
Amount
FROM YourTableName
) as s
PIVOT
(
SUM(Amount)
FOR [month] IN (jan, feb, mar, apr,
may, jun, jul, aug, sep, oct, nov, dec)
)AS pvt

Year months as Column and Fetch data

I have a table like this in SQL Server 2008
SalesMonth SalesPerson TotalAmount
----------- ----------- -----------
3 Ram 10000
3 Rajesh 25000
4 Rajesh 8500
6 Ram 12000
6 Anand 7000
11 Ram 6500
Results should be .....
SalesPerson Jan Feb Mar Apr Jun Jul Aug Sep Oct Nov Dec
Ram 0 0 10000 0 12000 0 0 0 0 6500 0
Rajesh 0 0 25000 8500 0 0 0 0 0 0 0
Anand 0 0 0 0 7000 0 0 0 0 0 0
Is it possible to get through sql query. If so, please help me...
Try to use PIVOT
SELECT SalesPerson,
ISNULL([1],0) as JAN,
ISNULL([2],0) as FEB,
ISNULL([3],0) as MAR,
ISNULL([4],0) as APR,
ISNULL([5],0) as MAY,
ISNULL([6],0) as JUN,
ISNULL([7],0) as JUL,
ISNULL([8],0) as AUG,
ISNULL([9],0) as SEP,
ISNULL([10],0) as OCT,
ISNULL([11],0) as NOV,
ISNULL([12],0) as DEC
FROM t
PIVOT
( SUM(TotalAmount)
FOR SalesMonth IN
([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS PivotTable
ORDER BY SalesPerson;
SQLFiddle demo
You will need to use the SQL Server's PIVOT operator:
SELECT SalesPerson, [Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec]
FROM (
SELECT MonthName.SalesMonthName, Sales.SalesPerson, Sales.TotalAmount
FROM Sales
INNER JOIN MonthName ON ( MonthName.MonthNumber = Sales.SalesMonth )
) AS SourceTable
PIVOT (
Sum(TotalAmount)
FOR SalesMonthName IN ([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])
) AS PivotTable
Also, since PIVOT aggregates data, the example above uses the Sum() function. (You could just as easily use Avg(), or a different aggregation function, based upon your needs.)
Your output will be NULL for all elements that do not have values.
NOTE: In the example above, I made an assumption that there is a fictional table (MonthName) that translates month numbers (1, 2,...) to month names (Jan, Feb,...), since your data does not show the 'jump' from month numbers to month names. If you do not want to do this, replace [Jan], [Feb], ..., [Nov], [Dec] with [1], [2], ..., [11], [12] in the SQL statement above (and, of course, remove the INNER JOIN).
SELECT SalesPerson,
[1] as jan, [2] as feb, [3] as mar, [4] as apr, [5] as may, [6] as jun, [7] as jul
, [8] as aug,[9] as sept,[10] as oct,[11] as nov,[12] as decm
FROM
table1
PIVOT
(
sum(TotalAmount)
FOR SalesMonth IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) AS PivotTable;