January 30, 2012 at 4:01 am
Hi all,
I have a table with ten thousands of rows that looks something like this:
CREATE TABLE #temp
(
company VARCHAR(50) NOT NULL,
details VARCHAR (200) NULL ,
details2 VARCHAR (200) NULL ,
code VARCHAR (50) NULL
)
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0321')
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0654')
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0987')
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUL12', NULL)
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUG58', NULL)
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUJ51', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH582', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH520', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH008', NULL)
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '9804')
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '2356')
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '0070')
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUV15', NULL)
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUT92', NULL)
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUY30', NULL)
I would like to see one row only for each company in the following format:
company code-merged str-merged
td tech 0321, 0654, 0987 publishing: PUL12, PUG58, PUJ51, pharma:PH582, PH520, PH008
op tech 9804, 2356, 0070 publishing: PUV15, PUT92, PUY30
I'm trying to merge the strings into one row using for xml path eg.
SELECT code + ', ' FROM #temp WHERE company = 'td tech' AND details IS null for xml path('')
This does the first only. Any way to do this on the entire table dynamically?
thanks
__________________________
Allzu viel ist ungesund...
January 30, 2012 at 4:22 am
Maybe this?
WITH CTE AS (
SELECT company,details,details2,
ROW_NUMBER() OVER(PARTITION BY company,details
ORDER BY details2) AS rn
FROM #temp
WHERE details IS NOT NULL)
SELECT a.company,
STUFF((SELECT ', ' + b.code AS "text()"
FROM #temp b
WHERE b.company=a.company
AND b.code IS NOT NULL
ORDER BY b.code
FOR XML PATH('')),1,2,'') AS [code-merged],
(SELECT CASE WHEN c.rn=1 THEN ' ' + c.details+': ' ELSE ', ' END +
c.details2 AS "text()"
FROM CTE c
WHERE c.company=a.company
ORDER BY c.details2
FOR XML PATH('')) AS [str-merged]
FROM #temp a
GROUP BY a.company;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537January 30, 2012 at 4:29 am
Here's a couple of options: -
BEGIN TRAN
CREATE TABLE #temp(
company VARCHAR(50) NOT NULL,
details VARCHAR (200) NULL ,
details2 VARCHAR (200) NULL ,
code VARCHAR (50) NULL)
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0321')
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0654')
INSERT INTO #temp VALUES( 'td tech', NULL, NULL, '0987')
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUL12', NULL)
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUG58', NULL)
INSERT INTO #temp VALUES( 'td tech', 'publishing', 'PUJ51', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH582', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH520', NULL)
INSERT INTO #temp VALUES( 'td tech', 'pharma', 'PH008', NULL)
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '9804')
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '2356')
INSERT INTO #temp VALUES( 'op tech', NULL, NULL, '0070')
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUV15', NULL)
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUT92', NULL)
INSERT INTO #temp VALUES( 'op tech', 'publishing', 'PUY30', NULL)
--Option 1
SELECT company,
COALESCE(STUFF((SELECT ', ' + code
FROM #temp t2
WHERE t2.company = t1.company AND t2.details IS NULL
FOR XML PATH('')), 1, 2, ''),'') +
COALESCE(' publishing: ' + STUFF((SELECT ', ' + details2
FROM #temp t3
WHERE t3.company = t1.company AND t3.details = 'publishing'
FOR XML PATH('')), 1, 2, ''),'') +
COALESCE(' pharma: ' + STUFF((SELECT ', ' + details2
FROM #temp t4
WHERE t4.company = t1.company AND t4.details = 'pharma'
FOR XML PATH('')), 1, 2, ''),'') AS ConcatenatedString
FROM #temp t1
GROUP BY company
--Option 2
SELECT company,
(SELECT grpCodes.grpCode
FROM (SELECT ', ' + code
FROM #temp t2
WHERE t2.company = t1.company AND t2.details IS NULL
FOR XML PATH(''), TYPE) codes(code)
CROSS APPLY (SELECT STUFF(codes.code.value('./text()[1]', 'VARCHAR(MAX)'),1,2,'')) grpCodes(grpCode)) +
COALESCE(' publishing: ' + (SELECT grpDetails2.grpDetail2
FROM (SELECT ', ' + details2
FROM #temp t3
WHERE t3.company = t1.company AND t3.details = 'publishing'
FOR XML PATH(''), TYPE) details2(detail2)
CROSS APPLY (SELECT STUFF(details2.detail2.value('./text()[1]', 'VARCHAR(MAX)'),1,2,'')) grpDetails2(grpDetail2)),'') +
COALESCE(' pharma: ' + (SELECT grpDetails2.grpDetail2
FROM (SELECT ', ' + details2
FROM #temp t4
WHERE t4.company = t1.company AND t4.details = 'pharma'
FOR XML PATH(''), TYPE) details2(detail2)
CROSS APPLY (SELECT STUFF(details2.detail2.value('./text()[1]', 'VARCHAR(MAX)'),1,2,'')) grpDetails2(grpDetail2)),'') AS ConcatenatedString
FROM #temp t1
GROUP BY company
ROLLBACK
Both return -
company ConcatenatedString
-------------------------------------------------- -----------------------------------------------------------------------------
op tech 9804, 2356, 0070 publishing: PUV15, PUT92, PUY30
td tech 0321, 0654, 0987 publishing: PUL12, PUG58, PUJ51 pharma: PH582, PH520, PH008
Based on Mark's very clever script, option 3: -
SELECT company,
(SELECT CASE WHEN t2.rn=1
THEN COALESCE(' ' + t2.details + ': ','') ELSE ', ' END + COALESCE(t2.details2, t2.code)
FROM (SELECT company, details2, details, code,
ROW_NUMBER() OVER(PARTITION BY company,details ORDER BY details2) AS rn
FROM #temp) t2
WHERE t2.company = t1.company
ORDER BY t2.details2
FOR XML PATH(''))
FROM #temp t1
GROUP BY company
January 30, 2012 at 5:20 am
Brilliant! Thanks for your time and have a good week!
__________________________
Allzu viel ist ungesund...
Viewing 4 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply