Click here to Skip to main content
15,908,444 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi I want to append the 5th Column as "Leave",I am getting the below result with this query

Empname Deptname LeaveType TotalLeave

Andrew CSE SickLeave 3

George IT CasualLeave 1

Andrew CSE CasualLeave 2

George IT SickLeave 2


Select EmployeeDetails.Empname,DepartmentDetails.Deptname ,LeaveApplication.LeaveType,Sum(LeaveApplication.NoOfDays) As TotalLeave 
From DepartmentDetails 
Inner JOIN EmployeeDetails on EmployeeDetails.DeptID = DepartmentDetails.DeptID
INNER JOIN LeaveApplication On EmployeeDetails.EmpID = LeaveApplication.EmpID
Where  LeaveApplication.LeaveFromDate >='2017-01-01' AND LeaveApplication.LeaveFromDate <='2017-05-31' and  EmployeeDetails.Status=0 and LeaveApplication.leavetype not in ('Forgot Access Card','Permission','Work from Home','Holiday Allowance/Weekend Allowance','On Duty','Night Shift Allowance') and LeaveApplication.LeaveStatus<>'Rejected'
GROUP BY LeaveApplication.EmpID ,DepartmentDetails.Deptname,EmployeeDetails.Empname,LeaveApplication.LeaveType
is my query




Result Needed Like

Empname Deptname LeaveType TotalLeave

Andrew CSE SickLeave,Casual 5

George IT CasualLeave,Sickleave 3

What I have tried:

Select EmployeeDetails.Empname,DepartmentDetails.Deptname ,LeaveApplication.LeaveType,Sum(LeaveApplication.NoOfDays) As TotalLeave 
From DepartmentDetails 
Inner JOIN EmployeeDetails on EmployeeDetails.DeptID = DepartmentDetails.DeptID
INNER JOIN LeaveApplication On EmployeeDetails.EmpID = LeaveApplication.EmpID
Where  LeaveApplication.LeaveFromDate >='2017-01-01' AND LeaveApplication.LeaveFromDate <='2017-05-31' and  EmployeeDetails.Status=0 and LeaveApplication.leavetype not in ('Forgot Access Card','Permission','Work from Home','Holiday Allowance/Weekend Allowance','On Duty','Night Shift Allowance') and LeaveApplication.LeaveStatus<>'Rejected'
GROUP BY LeaveApplication.EmpID ,DepartmentDetails.Deptname,EmployeeDetails.Empname,LeaveApplication.LeaveType
Posted
Updated 23-May-17 7:12am
v2
Comments
RickZeeland 23-May-17 15:59pm    
I would like to remark that in PostgreSQL this can be accomplished simply by using the string_agg() function:
select string_agg(leavetype, ',')

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
SQL
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
SQL
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.
SQL
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:
SQL
;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
 
Share this answer
 
Try this method............
DECLARE @Table1 TABLE(name varchar(20),branch varchar(20),leavetype varchar(20),noofleaves  INT)
INSERT INTO @Table1 VALUES ('A','CSE','sick',2),('B','IT','cough',1),('A','cse','allergy',4),('B','xx','vomit',2)


SELECT  name
       ,STUFF((SELECT ', ' + CAST(leavetype AS VARCHAR(10)) [text()]
         FROM @Table1 
         WHERE name = t.name and branch=t.branch
         FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,2,' ') List_Output
        ,sum(noofleaves)
FROM @Table1 t
GROUP BY name,branch
 
Share this answer
 
v3
Comments
CHill60 23-May-17 7:55am    
Nice, but only a 4* ... OP might struggle to apply this to their table structure.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900