May 17, 2010 at 5:55 am
This is scripts of three tables.
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Empmaster](
[EmpId] [int] NOT NULL,
[EmpName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Salary] [int] NULL,
CONSTRAINT [PK_Empmaster] PRIMARY KEY CLUSTERED
(
[EmpId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
USE [Test]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[DeptMaster](
[DeptId] [int] NOT NULL,
[Deptname] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_DeptMaster] PRIMARY KEY CLUSTERED
(
[DeptId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[EmpMapping](
[EmpId] [int] NOT NULL,
[DeptId] [int] NOT NULL
) ON [PRIMARY]
This is the data of three tables
EmpIdEmpNameSalary
111Malli20000
112Reddy10000
113Rahim5000
114naga10000
DeptIdDeptname
1Developement
2testing
3Maintanance
4Database
5Marketing
EmpIdDeptId
1111
1112
1113
1124
1125
1135
1142
1143
Expected Result
EmpIdEmpnameSalaryDeptnames
111Malli20000Development,testing,Maintanance
112Reddy10000Database,Marketing
113Rahim5000Marketing
114naga10000testing,Maintanance
The above is the Expected result i want.Please help me on this.
Iam getting comma Separated values but that is not exacted as i am Expecting.
Malleswarareddy
I.T.Analyst
MCITP(70-451)
May 17, 2010 at 6:45 am
Malli, this will get you there
;WITH CTE AS
(
SELECT Map.EMpId, Dep.deptName
FROM [EmpMapping] Map
LEFT JOIN [DeptMaster] dep
ON Map.DeptId = dep.DeptId
),
Concat_Data AS
(
SELECT dep1.empid,
STUFF( ( SELECT ',' + dep2.deptName
FROM CTE dep2
WHERE dep2.empid = dep1.empid
ORDER BY dep2.deptName
FOR XML PATH('')
)
, 1, 1, '') AS Concat_Values
FROM CTE dep1
GROUP BY dep1.empid
)
SELECT Emp.EmpID, Emp.EmpName, Emp.Salary ,C.Concat_Values Depts
FROM [Empmaster] EMP
LEFT JOIN Concat_Data C
ON Emp.EmpId = C.EmpId
Tell us if this worked for you!
~Edit: Beautified the code; Fixed the trailing/leading comma!
May 17, 2010 at 6:50 am
You have provided the DDLs, alright, but what about the INSERT INTO scirpts for the sample data! It took me about 15 mins to format the data u had given and then code for the requirement! Please provide the whole set-up in a ready-to-use manner which will save a lot of time for both of us. One with 837 posts to his/her name must take care of this. 🙂
For any other who are planning to work on this , here is the complete set-up:
-- My test DB
Use Scratch
GO
IF OBJECT_ID('Empmaster') IS NOT NULL
DROP TABLE [dbo].[Empmaster]
CREATE TABLE [dbo].[Empmaster](
[EmpId] [int] NOT NULL,
[EmpName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Salary] [int] NULL,
CONSTRAINT [PK_Empmaster] PRIMARY KEY CLUSTERED
(
[EmpId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
IF OBJECT_ID('DeptMaster') IS NOT NULL
DROP TABLE [dbo].[DeptMaster]
CREATE TABLE [dbo].[DeptMaster](
[DeptId] [int] NOT NULL,
[Deptname] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_DeptMaster] PRIMARY KEY CLUSTERED
(
[DeptId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
IF OBJECT_ID('EmpMapping') IS NOT NULL
DROP TABLE [dbo].[EmpMapping]
CREATE TABLE [dbo].[EmpMapping](
[EmpId] [int] NOT NULL,
[DeptId] [int] NOT NULL
) ON [PRIMARY]
Sample data
INSERT INTO [Empmaster] (EmpId, EmpName ,Salary)
select 111 , 'Malli', 20000 union all
select 112 , 'Reddy', 10000 union all
select 113 ,'Rahim', 5000 union all
select 114 ,'naga' , 10000
select EmpId, EmpName ,Salary from [Empmaster]
INSERT INTO [DeptMaster] ( DeptId, Deptname)
select 1 ,'Developement' union all
select 2 ,'testing' union all
select 3 ,'Maintanance' union all
select 4 ,'Database' union all
select 5 ,'Marketing'
select DeptId, Deptname from [DeptMaster]
INSERT INTO [dbo].[EmpMapping] (EmpId, DeptId)
select 111, 1 union all
select 111, 2 union all
select 111, 3 union all
select 112, 4 union all
select 112, 5 union all
select 113, 5 union all
select 114, 2 union all
select 114, 3
😎
May 17, 2010 at 6:55 am
You are good.I thought that with For Xml it will work.
But i did not applied that logic.Beacause i did not written that queries using for xml.so did not got the solution.but can we get the same result with out using for xml.Because i tried it with out using for xml, but failed to get result exactly.
But your solution is good. but for last value in column there is comma. we want to remove that comma also. can we got the result without using for XML.
Malleswarareddy
I.T.Analyst
MCITP(70-451)
May 17, 2010 at 7:00 am
malleswarareddy_m (5/17/2010)
But your solution is good. but for last value in column there is comma. we want to remove that comma also
Please revisit the code i had given, i have fixed the trailing comma issue with the new code. 🙂
. can we got the result without using for XML.
There are many ways. I dont remember, but Paul White once coded a beauty using CLR. I will try to find that out for you.
May 17, 2010 at 7:00 am
I thought that want to put insert scripts but the table is available.that's why i copy & pasted.sorry for wasting your time.next time i will put complete script for queries.
Malleswarareddy
I.T.Analyst
MCITP(70-451)
May 17, 2010 at 7:04 am
malleswarareddy_m (5/17/2010)
I thought that want to put insert scripts but the table is available.that's why i copy & pasted.sorry for wasting your time.next time i will put complete script for queries.
No Mr.Reddy, dont be apologetic! Don't feel sorry also! I am never tired to help! It is "never wasting my time"! Am happy to help always!
In future, please make sure tat INSERTs are present, that wud suffice!
Cheers and happy learning! 🙂
May 17, 2010 at 7:04 am
good job on providing the table structures and the desired output;
if you had posted the INSERT INTO for the data, your question would be perfect!
to convert rows into a comma seperated list, you want to use the FOR XML to get teh data formattted the way you expect.
here's teh solution:
CREATE TABLE [dbo].[Empmaster](
[EmpId] [int] NOT NULL,
[EmpName] [varchar](50) NULL,
[Salary] [int] NULL,
CONSTRAINT [PK_Empmaster] PRIMARY KEY CLUSTERED
(
[EmpId] ASC
)
)
GO
CREATE TABLE [dbo].[DeptMaster](
[DeptId] [int] NOT NULL,
[Deptname] [varchar](50) NULL,
CONSTRAINT [PK_DeptMaster] PRIMARY KEY CLUSTERED
(
[DeptId] ASC
)
)
CREATE TABLE [dbo].[EmpMapping](
[EmpId] [int] NOT NULL,
[DeptId] [int] NOT NULL
)
INSERT INTO Empmaster
(EmpId,EmpName,Salary)
SELECT '111','Malli','20000' UNION ALL
SELECT '112','Reddy','10000' UNION ALL
SELECT '113','Rahim','5000' UNION ALL
SELECT '114','naga','10000'
INSERT INTO DeptMaster
(DeptId, Deptname)
SELECT '1','Developement' UNION ALL
SELECT '2','testing' UNION ALL
SELECT '3','Maintanance' UNION ALL
SELECT '4','Database' UNION ALL
SELECT '5','Marketing'
--SELECT EmpMapping.EmpId, EmpMapping.DeptId,DeptMaster.Deptname FROM EmpMapping INNER JOIN DeptMaster ON EmpMapping.DeptId=DeptMaster.DeptId
INSERT INTO EmpMapping
(EmpId,DeptId)
SELECT '111','1' UNION ALL
SELECT '111','2' UNION ALL
SELECT '111','3' UNION ALL
SELECT '112','4' UNION ALL
SELECT '112','5' UNION ALL
SELECT '113','5' UNION ALL
SELECT '114','2' UNION ALL
SELECT '114','3'
--EmpId Empname Salary Deptnames
SELECT EmpId,
Empname,
Salary ,stuff(( SELECT ',' + Deptname
FROM (SELECT
EmpMapping.EmpId,
EmpMapping.DeptId,
DeptMaster.Deptname
FROM EmpMapping
INNER JOIN DeptMaster
ON EmpMapping.DeptId=DeptMaster.DeptId) s2
WHERE s2.EmpId= s1.EmpId --- must match GROUP BY below
ORDER BY Deptname
FOR XML PATH('')
),1,1,'') as Deptnames
FROM (SELECT
EmpMapping.EmpId,
Empmaster.EmpName,
Empmaster.Salary,
EmpMapping.DeptId,
DeptMaster.Deptname
FROM EmpMapping
INNER JOIN DeptMaster
ON EmpMapping.DeptId=DeptMaster.DeptId
INNER JOIN Empmaster
ON EmpMapping.EmpId = Empmaster.EmpId
) s1
GROUP BY s1.EmpId,EmpName,Salary --- without GROUP BY multiple rows are returned
ORDER BY s1.EmpId,EmpName,Salary
Lowell
May 17, 2010 at 7:11 am
Another variant of the code. This will also perform the same
;WITH Master_CTE AS
(
SELECT
Emp.EmpID, Emp.EmpName, Emp.Salary ,dep.DeptName
FROM
[Empmaster] EMP
LEFT JOIN [EmpMapping] Map
ON Emp.EmpId = Map.EmpId
LEFT JOIN [DeptMaster] dep
ON dep.deptId = Map.Deptid
)
SELECT A.EmpID, A.EmpName, A.Salary ,
STUFF( ( SELECT ',' + B.DeptName
FROM Master_CTE B
WHERE B.EmpID = A.EmpID
ORDER BY B.DeptName
FOR XML PATH('')
)
, 1, 1, '') AS DeptName
FROM Master_CTE A
GROUP BY
A.EmpID, A.EmpName, A.Salary
May 17, 2010 at 7:13 am
There is another way using T-SQL to concatentate values that needs to be used in versions prior to SQL Server 2005, problem is that it does not scale as well as the FOR XML PATH method.
There also was a thread devoted to numerous methods of doing this as well, but I don't have a reference to it handy. Hopefully someone else may have it and could provide it.
May 17, 2010 at 7:25 am
thanks for quick reply.This is the interview question i had faced in two interviews. and i told to interviewer that we can acheive that using For XML.but i did not written that.
Malleswarareddy
I.T.Analyst
MCITP(70-451)
May 17, 2010 at 9:49 pm
:Whistling:
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply