Not a solution to this specific problem but a "solution" is the best way to present some advice that might help you when you come across problems later.
1. Consider using short aliases for your tables rather than having to repeat the full table name every time. Vishwanth Raya has used an alias in his solution and here is what your original query would look like if you did the same
Select ED.Empname,DepartmentDetails.DD ,LA.LeaveType,Sum(LA.NoOfDays) As TotalLeave
From DepartmentDetails DD
Inner JOIN EmployeeDetails ED on ED.DeptID = DD.DeptID
INNER JOIN LeaveApplication LA On ED.EmpID = LA.EmpID
Where LA.LeaveFromDate >='2017-01-01' AND LA.LeaveFromDate <='2017-05-31' and ED.Status=0 and LA.leavetype not in ('Forgot Access Card','Permission','Work from Home','Holiday Allowance/Weekend Allowance','On Duty','Night Shift Allowance') and LA.LeaveStatus<>'Rejected'
GROUP BY LA.EmpID ,DD.Deptname,ED.Empname,LA.LeaveType
2. If you are using a version of SQL Server from 2008 onwards then the
BETWEEN
operator on dates is much tidier. Also consider using linebreaks and whitespace to make your query easier to read. Here's your original query again, with all of these suggestions added
Select ED.Empname,DepartmentDetails.DD ,LA.LeaveType,Sum(LA.NoOfDays) As TotalLeave
From DepartmentDetails DD
Inner JOIN EmployeeDetails ED on ED.DeptID = DD.DeptID
INNER JOIN LeaveApplication LA On ED.EmpID = LA.EmpID
Where LA.LeaveFromDate BETWEEN '2017-01-01' AND '2017-05-31' and ED.Status=0
and LA.leavetype not in ('Forgot Access Card','Permission','Work from Home','Holiday Allowance/Weekend Allowance','On Duty','Night Shift Allowance')
and LA.LeaveStatus<>'Rejected'
GROUP BY LA.EmpID ,DD.Deptname,ED.Empname,LA.LeaveType
3. Consider taking the normalisation of your schema down to another level. You are repeating a lot of text when it comes to LeaveApplication and the list of Leave types to omit. You should have another table for
LeaveType
that contains the text of the leave type and whether or not it should be included in the query e.g.
DECLARE @LeaveType TABLE (id int identity(1,1), LeaveType nvarchar(40), Acceptable bit)
INSERT INTO @LeaveType (LeaveType, Acceptable) VALUES
('SickLeave',1),('CasualLeave',1),
('Forgot Access Card',0),('Permission',0),('Work from Home',0),
('Holiday Allowance/Weekend Allowance',0),('On Duty',0),('Night Shift Allowance',0)
LeaveType
in LeaveApplication should be an integer foreign key to this new table E.G.
DECLARE @LeaveApplication TABLE(EmpID INT, LeaveType INT, LeaveFromDate date, LeaveStatus varchar(20), NoOfDays INT)
insert into @LeaveApplication (EmpID, LeaveType, LeaveFromDate, LeaveStatus, NoOfDays) values
(1, 1, '2017-02-14', 'Accepted', 3),
(1, 2, '2017-03-15','Accepted',2),
(2, 2, '2017-03-15','Accepted',1),
(2, 1, '2017-03-15','Accepted',2),
(1, 4, '2017-03-20','Accepted',1),
(2, 7, '2017-03-20','Accepted',1)
4. You can also use sub-queries and Common Table Expressions to make your queries easier to understand, easier to build and easier to debug. For example I could place your (now amended) original query into a CTE. I can then treat that as if it was the sample table from Solution 1 - making it easier to apply the technique:
;WITH QRY AS
(
SELECT ED.Empname,DD.Deptname ,I.LeaveType, SUM(LA.NoOfDays) As TotalLeave
FROM @DepartmentDetails DD
Inner JOIN @EmployeeDetails ED on ED.DeptID = DD.DeptID
INNER JOIN @LeaveApplication LA On ED.EmpID = LA.EmpID
INNER JOIN @LeaveType I ON I.id = LA.LeaveType AND I.Acceptable = 1
Where LA.LeaveFromDate BETWEEN '2017-01-01' AND '2017-05-31'
and ED.[Status]=0 and LA.LeaveStatus<>'Rejected'
GROUP BY LA.EmpID ,DD.Deptname,ED.Empname,I.LeaveType
)
SELECT EmpName, DeptName
,STUFF((SELECT ', ' + CAST(LeaveType AS VARCHAR(20)) [text()]
FROM QRY
WHERE Empname = t.Empname
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') List_Output,sum(TotalLeave) AS TotalLeave
FROM QRY t
GROUP BY EmpName, DeptName