Month and year wise report - sql

I want to show a table that months are vertical and years are horizontal, I give an input of year and month that is from a dropdownlist.
My expected output is below:
2011 2012 2013 2014
jan 1000 1500 5000 1000
feb 00 00 2000 2000
mar .
. .
. .
dec .
My query is
select
datepart(year, DateOfTransaction),
left(datepart(month, DateOfTransaction), 3),
sum(amount)
from TBL_Transactionmaster
where
datepart(year, DateOfTransaction) = 'input year'
and datepart(month, DateOfTransaction) = 'input month'

Try this query .
For Static Pivot
SELECT *
FROM (
SELECT
left(datename(month,DateOfTransaction),3)as [month], year(DateOfTransaction) as [year]
, Amount
FROM TBL_Transactionmaster
) as s
PIVOT
(
SUM(Amount)
FOR [Year] in([2011],[2012],[2013],[2014],[2015])
)AS piv
For Dynamic Pivot
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(year(DateOfTransaction))
from TBL_Transactionmaster
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT [Month],' + #cols + ' from
(
SELECT
left(datename(month,DateOfTransaction),3)as [month], year(DateOfTransaction) as [year]
, Amount
FROM TBL_Transactionmaster
) x
pivot
(
sum(amount)
for [year] in (' + #cols + ')
) p '
execute(#query)
**For All Month and Replace Null with 0 **
SELECT [month], Isnull([2011],0) as [2011] , ISnull([2012],0) as [2012] ,ISNULL ([2013],0) as [2013] , ISNULL([2014],0) as [2014] , ISNULL([2015],0) as [2015]
FROM (
SELECT
left(datename(month,DateOfTransaction),3)as [month], Amount, year(DateOfTransaction) as [year]
FROM TBL_Transactionmaster
UNION ALL
select [MONTH], Amount, [year] FROM
(Select 'Jan' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Feb' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Mar' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Apr' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'May' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Jun' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Jul' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Aug' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Sep' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Oct' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Nov' as [Month] , 0 as Amount, year(Getdate()) as [year] Union ALL
Select 'Dec' as [Month] , 0 as Amount, year(Getdate()) as [year] ) MN
) as s
PIVOT
(
SUM(Amount)
FOR [Year] in([2011],[2012],[2013],[2014],[2015])
)AS piv

You can use a query like this:
SELECT DATENAME(MONTH, DateOfTransaction) As [Month]
, SUM(CASE WHEN DATEPART(YEAR, DateOfTransaction) = 2011 THEN amount ELSE 0 END) AS [2011]
, SUM(CASE WHEN DATEPART(YEAR, DateOfTransaction) = 2012 THEN amount ELSE 0 END) AS [2012]
, SUM(CASE WHEN DATEPART(YEAR, DateOfTransaction) = 2013 THEN amount ELSE 0 END) AS [2013]
, SUM(CASE WHEN DATEPART(YEAR, DateOfTransaction) = 2014 THEN amount ELSE 0 END) AS [2014]
FROM TBL_Transactionmaster
GROUP BY DATENAME(MONTH, DateOfTransaction), DATEPART(MONTH, DateOfTransaction)
ORDER BY DATEPART(MONTH, DateOfTransaction)
You can use Dynamic SQL like this:
DECLARE #sql nvarchar(max);
SELECT #sql = ISNULL(#sql, 'DATENAME(MONTH, DateOfTransaction) As [Month]') + ', SUM(CASE WHEN DATEPART(YEAR, DateOfTransaction) = ' +
CAST(DATEPART(YEAR, DateOfTransaction) AS VARCHAR(5)) + ' THEN amount ELSE 0 END) AS [' + CAST(DATEPART(YEAR, DateOfTransaction) AS varchar(5)) + ']'
FROM TBL_Transactionmaster
GROUP BY DATEPART(YEAR, DateOfTransaction)
ORDER BY DATEPART(YEAR, DateOfTransaction);
SET #sql = 'SELECT ' + #sql + ' FROM TBL_Transactionmaster GROUP BY DATENAME(MONTH, DateOfTransaction), DATEPART(MONTH, DateOfTransaction) ORDER BY DATEPART(MONTH, DateOfTransaction)';
EXEC(#sql);

Related

SQL Server dynamic pivot table with dates as columns using CTE as my table? [duplicate]

This question already has answers here:
SQL Server dynamic PIVOT query?
(9 answers)
Closed 12 months ago.
So I have 36 month worth of data in my CTE, and the database is still active storing new data daily.
In my analysis, I just need 6 months worth of data from getdate()
So my question is that how do I make the month derived from calendar month the column of my table?
So for end of March 2022, this is the view that I should see:
id
name
10/01/21
11/01/21
12/01/21
01/01/22
02/01/22
03/01/2022
1
John
3
0
1
0
0
2
2
Mary
6
1
2
1
1
2
3
Angelo
1
5
3
2
2
0
4
Diane
3
2
0
1
0
6
So for the end of April 2022, this is the view that I should see:
id
name
11/01/21
12/01/21
01/01/22
02/01/22
03/01/2022
04/01/22
1
John
0
1
0
0
2
7
2
Mary
1
2
1
1
2
2
3
Angelo
5
0
0
0
0
3
4
Diane
2
0
1
0
6
4
You can't have a dynamic PIVOT without dynamic SQL. I find it's easiest to break it up into parts.
Get the last 6 months
DECLARE #thisMonth date, #firstMonth date;
SET #thisMonth = DATEFROMPARTS(YEAR(getdate()), MONTH(getdate()), 1);
SET #firstMonth = DATEADD(MONTH, -5, #thisMonth);
;WITH m(m) AS
(
SELECT #firstMonth
UNION ALL
SELECT DATEADD(MONTH, 1, m) FROM m
WHERE m < #thisMonth
)
SELECT m FROM m ORDER BY m DESC;
Output:
m
2022-03-01
2022-02-01
2022-01-01
2021-12-01
2021-11-01
2021-10-01
Figure out what manual query you need. Given this sample data:
CREATE TABLE dbo.JetSales
(
ID int,
Name nvarchar(32),
SalesDate date
);
INSERT dbo.JetSales(ID, Name, SalesDate) VALUES
(1,N'John','20211005'),(1,N'John','20211016'),(1,N'John','20211031'),
(2,N'Mary','20211007'),(2,N'Mary','20211013'),
(3,N'Tank','20211009');
I think you want a query like this (yes, you can accomplish this specific task with PIVOT too, but PIVOT doesn't cover some other scenarios, and it also requires pre-aggregation in this case... so I think conditional aggregation is better):
SELECT ID, Name,
[10/01/2021] = SUM(CASE WHEN SalesDate >= '20211001'
AND SalesDate < '20211101' THEN 1 ELSE 0 END),
[11/01/2021] = SUM(CASE WHEN SalesDate >= '20211101'
AND SalesDate < '20211201' THEN 1 ELSE 0 END),
[12/01/2021] = SUM(CASE WHEN SalesDate >= '20211201'
AND SalesDate < '20220101' THEN 1 ELSE 0 END),
[01/01/2022] = SUM(CASE WHEN SalesDate >= '20220101'
AND SalesDate < '20220201' THEN 1 ELSE 0 END),
[02/01/2022] = SUM(CASE WHEN SalesDate >= '20220201'
AND SalesDate < '20220301' THEN 1 ELSE 0 END),
[03/01/2022] = SUM(CASE WHEN SalesDate >= '20220301'
AND SalesDate < '20220401' THEN 1 ELSE 0 END)
FROM dbo.JetSales AS js GROUP BY ID, Name;
Which you can build as follows:
DECLARE #thisMonth date, #firstMonth date;
SET #thisMonth = DATEFROMPARTS(YEAR(getdate()), MONTH(getdate()), 1);
SET #firstMonth = DATEADD(MONTH, -5, #thisMonth);
DECLARE #sql nvarchar(max) = N'SELECT ID, Name';
;WITH m(m) AS
(
SELECT #firstMonth
UNION ALL
SELECT DATEADD(MONTH, 1, m) FROM m
WHERE m < #thisMonth
)
SELECT #sql += N',
' + QUOTENAME(CONVERT(char(10), m, 101))
+ N' = SUM(CASE WHEN SalesDate >= '
+ QUOTENAME(CONVERT(char(8), m, 112), char(39)) + N'
AND SalesDate < '
+ QUOTENAME(CONVERT(char(8), DATEADD(MONTH, 1, m), 112), char(39))
+ N' THEN 1 ELSE 0 END)'
FROM m;
SET #sql += N'
FROM dbo.JetSales AS js GROUP BY ID, Name;';
SELECT #sql;
EXEC sys.sp_executesql #sql;
Working example: db<>fiddle
If you really want to use PIVOT explicitly, you can, it's just a lot more cumbersome. Here's the query you want to end up with:
;WITH src AS
(
SELECT ID, Name, m = CONVERT(char(10),
DATEFROMPARTS(YEAR(SalesDate), Month(SalesDate), 1), 101)
FROM dbo.JetSales
WHERE SalesDate >= #firstMonth
),
agg AS
(
SELECT ID, Name, m, c = COUNT(*)
FROM src GROUP BY ID, Name, m
)
SELECT ID, Name,
[10/01/2021] = COALESCE([10/01/2021], 0),
[11/01/2021] = COALESCE([11/01/2021], 0),
[12/01/2021] = COALESCE([12/01/2021], 0),
[01/01/2022] = COALESCE([01/01/2022], 0),
[02/01/2022] = COALESCE([02/01/2022], 0),
[03/01/2022] = COALESCE([03/01/2022], 0)
FROM agg PIVOT (SUM(c) FOR m IN (
[10/01/2021],[11/01/2021],[12/01/2021],
[01/01/2022],[02/01/2022],[03/01/2022]
)) AS p;
To get there:
DECLARE #thisMonth date, #firstMonth date;
SET #thisMonth = DATEFROMPARTS(YEAR(getdate()), MONTH(getdate()), 1);
SET #firstMonth = DATEADD(MONTH, -5, #thisMonth);
DECLARE #col1 nvarchar(max) = N'',
#col2 nvarchar(max) = N'',
#sql nvarchar(max) = N';WITH src AS
(
SELECT ID, Name, m = CONVERT(char(10),
DATEFROMPARTS(YEAR(SalesDate), Month(SalesDate), 1), 101)
FROM dbo.JetSales
WHERE SalesDate >= #firstMonth
),
agg AS
(
SELECT ID, Name, m, c = COUNT(*)
FROM src GROUP BY ID, Name, m
)
SELECT ID, Name,';
;WITH m(m) AS
(
SELECT #firstMonth
UNION ALL
SELECT DATEADD(MONTH, 1, m) FROM m
WHERE m < #thisMonth
),
x(x) AS
(
SELECT QUOTENAME(CONVERT(char(10), m, 101)) FROM m
)
SELECT
#col1 += STRING_AGG(CONCAT(N'
', x, N' = COALESCE(', x, ',0)'),N','),
#col2 += STRING_AGG(x, N',
')
FROM x;
SET #sql += #col1 + N'
FROM agg PIVOT (SUM(c) FOR m IN ('
+ #col2 + N'
)) AS p;';
SELECT #sql;
EXEC sys.sp_executesql #sql, N'#firstMonth date', #firstMonth;
Another fiddle here: db<>fiddle

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) )));

How to get sum by MonthYear in sql?

I have a table like this
id Date Amount
1 2016-09-29 09:25:37.000 25.13
2 2016-08-01 17:20:39.000 598.00
3 2016-09-29 09:24:47.000 15.60
4 2016-07-28 17:50:11.000 61.80
5 2016-07-28 17:53:56.000 31.40
6 2016-07-22 10:40:27.000 74.16
I'm trying to get two columns like this,
MonthYear Total
Sep 2016 40.73
Aug 2016 598.00
Jul 2016 167.36
But, I want to get most recent year and month to top.
Try this sql,
SELECT CONVERT(CHAR(4), Date, 100) + CONVERT(CHAR(4), Date, 120)
AS MonthYear, SUM(Amount)
AS Total,
CAST(CONVERT(varchar(4), Date, 120) AS int)
AS Year, DATEPART(m, Date) As Month
FROM your_table
GROUP BY CONVERT(CHAR(4), Date, 100) + CONVERT(CHAR(4), Date,120),CAST(CONVERT(varchar(4), Date, 120) AS int), DATEPART(m, Date)
ORDER BY Year DESC, Month DESC
Just an other perspective.
Query
SELECT t.[MonthYear], SUM(t.[Amount]) AS [Total] FROM(
SELECT RIGHT((CONVERT(VARCHAR(11), [Date], 106)), 8) as [MonthYear], [Amount]
FROM [your_table_name]
)t
GROUP BY t.[MonthYear];
Try below
SELECT Datename(MONTH, [Date]) month_name,
Year([Date]) year,
Sum([Amount]),
Month([date]) month_no
FROM #Table1
GROUP BY Datename(MONTH, [Date]),
Year([Date]),
Month([date])
ORDER BY Month([date]) DESC,
Year([Date]),
Datename(MONTH, [Date])

SQL Year summary starting from given month

I have the following SQL query which Display 12 months of summary report from the given date. Output shows starting from January to December for whatever the given date. I want the outcome to start from the given date's month.
If the given date is '2016-05-01' I want the output to be like this
May 16 |June 16| July 16| ........... | Jan 17 | Feb 17 | March 17 | April 17 |
How can I achieve this?
Can some one suggest?
SELECT Name,SUM(Amount) AS PremiumTot,TotType,
sum(case when month(Dates) = 1 then Tot else 0 end) Jan,
sum(case when month(Dates) = 2 then Tot else 0 end) Feb,
sum(case when month(Dates) = 3 then Tot else 0 end) March,
sum(case when month(Dates) = 4 then Tot else 0 end) April,
sum(case when month(Dates) = 5 then Tot else 0 end) May,
sum(case when month(Dates) = 6 then Tot else 0 end) June,
sum(case when month(Dates) = 7 then Tot else 0 end) July,
sum(case when month(Dates) = 8 then Tot else 0 end) Aug,
sum(case when month(Dates) = 9 then Tot else 0 end) Sep,
sum(case when month(Dates) = 10 then Tot else 0 end) Oct,
sum(case when month(Dates) = 11 then Tot else 0 end) Nov,
sum(case when month(Dates) = 12 then Tot else 0 end) Dece
FROM
(
SELECT InvoiceMasterID,Dates ,Name,CompanyCommission AS Tot ,0 AS Expences,Amount,1 as TotType
FROM CommissionView
UNION ALL
SELECT InvoiceMasterID,Dates,Name, 0 AS Tot ,-AgentCommission AS Expences,Amount,2 as TotType
FROM CommissionViewCredit
) a
WHERE Dates between #fromDates AND Datesadd(yy,1,#fromDates)
GROUP BY Name,TotType
Seems, you want to pivot data. So, use PIVOT table!
If you want to create dynamic columns from given date, use CTE (Common Table Expressions)!
--declare variables for given date range
DECLARE #startDate DATE = '2016-05-01'
DECLARE #endDate DATE = DATEADD(mm,11,#startDate)
--declare variable to store months as: [month1], [month2], [etc.]
DECLARE #Months VARCHAR(1000) = ''
--use cte to create range of dates
;WITH MyDates AS
(
SELECT #startDate AS MyDate
UNION ALL
SELECT DATEADD(mm,1,MyDate) AS MyDate
FROM MyDates
WHERE MyDate<#endDate
)
SELECT #Months = STUFF((SELECT '],[' + CONVERT(VARCHAR(7), MyDate, 121)
FROM MyDates
FOR XML PATH('')), 1, 2, '') + ']'
--PRINT #Months:
-- prints: [2016-05],[2016-06], ... ,[2017-04]
DECLARE #qry NVARCHAR(MAX) = ''
SET #qry = N'SELECT ' + #Months +
' FROM ( ' +
' SELECT CONVERT(VARCHAR(7), Dates, 121) AS MyDate, CompanyCommission AS Tot ' +
'FROM CommissionView ' +
') AS DT ' +
'PIVOT (SUM(Tot) FOR MyDate IN(' + #Months + ')) AS PT'
EXEC (#qry)
For further information, please see:
Dynamic PIVOT
Pivots with dynamic columns
CAST and CONVERT
Good luck!

CTC Annual History as a Pivot Table sql server

My table looks like below
select * from Salary_hist
EMPNAME CTC DateAdded
===========================
Ram 300000 2015-01-01
Ram 30000 2014-01-01
Ram 3000 2013-01-02
Ram 2700 2013-01-01
Ram 300 2012-01-01
Ram 30 2011-01-01
I am trying to make the output to show History increase for all employee based on Max Salary for a particular year
Output like
EMPNAME 2015 2014 2013 2012 2011
============================================
Ram 300000 30000 3000 300 30
Tried two method using rank and Alias but seems missing some thing.
select
Y.EMPNAME,
year(Y.DateAdded),
year(y.DateAdded)-2,
year(y.DateAdded)-3,
year(y.DateAdded)-4,
year(y.DateAdded)-5
from (
select X.EMPNAME,
max(case when rn = 1 then CTC end) as dateadded,
max(case when rn = 2 then CTC end) as dateadded1,
max(case when rn = 3 then CTC end) as dateadded2,
max(case when rn = 4 then CTC end) as dateadded3,
max(case when rn = 5 then CTC end) as dateadded4
from
(
select row_number() over (partition by empname order by dateadded desc) as rn,
empname,
CTC,
Dateadded
from Salary_hist
) X group by EMPNAME,dateadded)
y
And
select EMPNAME,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()) then CTC end) as dateadded,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()-1) then CTC end) as dateadded-1,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()-2) then CTC end) as dateadded-2,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()-3) then CTC end) as dateadded-3,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()-4 ) then CTC end) as dateadded-4,
max(case when DatePart(Year, dateadded) = DatePart(Year, GETDATE()-5) then CTC end) as dateadded-5
from Salary_hist
group by EMPNAME, dateadded)
You can do this in a much simple way using MAX with PARTITION BY and taking DISTINCT on it. You doesn't need a Sub-query here.
1. STATIC PIVOT
You can use this when the value of year is known in advance.
SELECT EMPNAME,[2015],[2014],[2013],[2012],[2011]
FROM
(
SELECT DISTINCT EMPNAME,MAX(CTC) OVER(PARTITION BY EMPNAME,YEAR(DATEADDED))MAXCTC,
YEAR(DATEADDED)PERIOD
FROM #TEMP
)S
PIVOT
(
MIN(MAXCTC)
FOR PERIOD IN([2015],[2014],[2013],[2012],[2011])
)P
Click here to view result
2. Dynamic pivot
You can use this if the values of year is unknown in advance.
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + YEAR + ']', '[' + YEAR + ']')
FROM (SELECT DISTINCT CAST(YEAR(DATEADDED)AS VARCHAR(4)) [YEAR] FROM #TEMP) PV
ORDER BY CAST([YEAR] AS INT) DESC
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT * FROM
(
SELECT DISTINCT EMPNAME,MAX(CTC) OVER(PARTITION BY EMPNAME,YEAR(DATEADDED))MAXCTC,
YEAR(DATEADDED)PERIOD
FROM #TEMP
) x
PIVOT
(
MIN(MAXCTC)
FOR PERIOD IN (' + #cols + ')
) p
ORDER BY EMPNAME;'
EXEC SP_EXECUTESQL #query
Click here to view result
With that kind of table structure making a select that returns start salary of the year in case there is no salary increase for that year and otherwise returns the max. salary makes it slightly more complex:
select
empname, [2011], [2012], [2013], [2014], [2015]
from
(
select
empname,
year(dateAdded) as year,
max(CTC) as CTC
from
salary_hist S
group by
empname,
year(dateAdded)
union all
select
S.empname,
Y.Year,
S.CTC
from
(select distinct year(DateAdded) as Year from Salary_hist) Y
outer apply (
select S.empname, S.CTC,
row_number() over
(partition by empname order by DateAdded desc) as RN
from Salary_Hist S
where DateAdded
<= convert(datetime, convert(varchar, Y.Year) + '0101', 112)
) S
where
S.RN = 1
) as S
pivot (
max (CTC) for year in ([2011],[2012],[2013],[2014],[2015])
) as P