I have 2 tables
Departments
ID Dept
---------
1 HR
2 Accts
3 IT
Employee
I
Looking beyond how you're storing your data, let me try to help you out.
Well, you're asking a lot of questions here. First, to split the data, you can format it as XML and use CROSS APPLY -- trick I saw a while back that didn't require built in functions.
That will convert your comma delimited string to a list of strings. You can then use FOR XML to put them back together.
Give this a shot:
SELECT
E.Id,
E.Name,
STUFF(
(
SELECT ',' + D.Department AS [text()]
FROM (
SELECT A.[id],
Split.a.value('.', 'VARCHAR(100)') AS DeptId
FROM
(SELECT [id],
CAST ('<M>' + REPLACE(Depts, ',', '</M><M>') + '</M>' AS XML) AS String
FROM Employee
) AS A
CROSS APPLY String.nodes ('/M') AS Split(a)) A
JOIN Departments D ON A.DeptId = D.Id
WHERE E.Id = A.Id
FOR XML PATH('')
), 1, 1, '') AS Departments
FROM Employee E
And here is the SQL Fiddle.
Good luck.
You can also use a recursive CTE to split the data and then use FOR XML PATH
to concatenate the rows into a single row:
;with cte (id, name, deptid, depts) as
(
select id, name,
cast(left(depts, charindex(',',depts+',')-1) as varchar(50)) deptid,
stuff(depts, 1, charindex(',',depts+','), '') depts
from employee
union all
select id, name,
cast(left(depts, charindex(',',depts+',')-1) as varchar(50)) deptid,
stuff(depts, 1, charindex(',',depts+','), '') depts
from cte
where depts > ''
)
select e.id, e.name,
stuff((
select distinct ', '+ d.dept
from cte c
inner join departments d
on c.deptid = d.id
where e.id = c.id
for XML path('')),1,1,'') Depts
from employee e
See SQL Fiddle with Demo
Result:
| ID | NAME | DEPTS |
----------------------------------
| 1 | Kevin | Accts, HR |
| 2 | Michelle | HR |
| 3 | Troy | HR, IT |
| 4 | Rheesa | Accts, HR, IT |
Write a function for splitting comma separated values. I wrote dbo.split
select * from dbo.split('1,2,3',',') Will return as - Data 1 2 3
SELECT tact.ActivityID,CONVERT(NVARCHAR(20),tact.createddate,103) AS CallDate,
ActivityOriginatedByPartyID , (ISNULL(p.firstname,'')+' '+ISNULL(p.lastname,'')) AS PartnerName,
u.UserName AS PSTName, ccv.codevalue AS CallType
**, ccv1.codevalue AS CallContext**
,tact.ActivityNote AS CallTrackerNote,
(CONVERT(VARCHAR(20),tact.ActivityTimeSpend) + ' Min') AS CallDuration
FROM txn_activity tact (NOLOCK)
INNER JOIN TXN_Party p (NOLOCK) ON p.PartyID = tact.ActivityOriginatedByPartyID
INNER JOIN TXN_User u (NOLOCK) ON u.userid = tact.createdby
INNER JOIN CFG_CodeValue ccv (NOLOCK) ON ccv.codevalueid = tact.ActivityTypeID
--INNER JOIN CFG_CodeValue ccv1 (NOLOCK) ON ccv1.codevalueid = tact.ActivityContext
**CROSS APPLY
dbo.split(tact.ActivityContext,',') split
inner join
dbo.CFG_CodeValue ccv1 (NOLOCK) ON ccv1.codevalueid = split.data**
DECLARE @Departments TABLE
(
ID INT PRIMARY KEY,
Dept VARCHAR(32) NOT NULL UNIQUE
);
DECLARE @Employees TABLE
(
ID INT PRIMARY KEY,
Name NVARCHAR(64) NOT NULL,
Depts VARCHAR(255) NOT NULL
);
INSERT @Departments VALUES
(1,'HR'), (2,'Accts'), (3,'IT');
INSERT @Employees VALUES
(1,'Kevin','2,1'), (2,'Michelle','1'),
(3,'Troy','1,3'), (4,'Rheesa','2,3,1');
SELECT ID, Name, Depts = STUFF((SELECT ',' + d.Dept
FROM @Departments AS d
INNER JOIN @Employees AS ei
ON ',' + ei.Depts + ',' LIKE '%,' + CONVERT(VARCHAR(12), d.id) + ',%'
WHERE ei.ID = e.ID
ORDER BY Dept
FOR XML PATH, TYPE).value('.[1]', 'nvarchar(max)'), 1, 1, '')
FROM @Employees AS e
ORDER BY ID;
The results don't quite match your required results, as the ordering is deterministic (ordered by department name):
ID Name Depts
---- -------- ----
1 Kevin Accts,HR
2 Michelle HR
3 Troy HR,IT
4 Rheesa Accts,HR,IT
If you want them ordered by the appearance in the comma-separated list, just change:
ORDER BY Dept
To:
ORDER BY CHARINDEX( ',' + CONVERT(VARCHAR(12), d.id) + ',', ',' + ei.Depts + ',')
Results:
ID Name Depts
---- -------- ----
1 Kevin Accts,HR
2 Michelle HR
3 Troy HR,IT
4 Rheesa Accts,IT,HR -- this is the only one affected as it turns out
However, in reality, you should normalize your database. This is an absolute nightmare.
Also you can use option with dynamic management function sys.dm_fts_parser
Before script execution you need check full-text component is installed:
SELECT FULLTEXTSERVICEPROPERTY ('IsFulltextInstalled')
0 = Full-text is not installed. 1 = Full-text is installed. NULL = Invalid input, or error.
If 0 = Full-text is not installed then this post is necessary to you How to install fulltext on sql server 2008?
SELECT b.ID, b.Name, STUFF((
SELECT ',' + d.Dept
FROM Employees e
JOIN Departments d ON d.ID IN(
SELECT display_term
FROM sys.dm_fts_parser('"' + e.Depts + '"', 1033, NULL, 0)
WHERE display_term NOT LIKE 'nn%'
)
WHERE b.ID = e.ID
ORDER BY d.Dept
FOR XML PATH('')), 1, 1, '') AS Depts
FROM Employees b
OR
SELECT e.ID, e.Name,
(
STUFF((
SELECT ',' + Dept
FROM sys.dm_fts_parser('"' + e.Depts + '"', 1033, NULL, 0) p JOIN Departments d ON p.display_term = d.ID
WHERE display_term NOT LIKE 'nn%'
FOR XML PATH('')), 1, 1, '')
) AS Depts
FROM Employees e