i have on sql server 2008 table like
EmployeeCertificationHistoryId EmployeeCertificationID EmployeeID CertificationID CertificationDate
1 244 2192 1 2/15/2006
2 185 2058 87 4/10/2010
3 245 2240 102 8/11/2013
4 246 2249 104 11/23/2005
5 247 2221 101 6/12/2013
6 248 2238 84 NULL
7 245 2240 102 8/11/2013
8 249 2240 102 8/4/2013
10 253 2175 84 6/19/2013
11 254 2239 105 2/5/2011
12 255 2239 111 11/22/2012
9 96 1468 92 12/6/2010
13 256 2239 110 11/22/2012
i need to comma seperate certificationid per employeeid.
for eg. for 2239=>105,111,110
i have written a query but it is giving all certificate id in one column. my query is
SELECT STUFF(
(SELECT ',' + CAST(C.CertificationID AS VARCHAR(100))
FROM tbl_PM_EmployeeCertificationMatrixHistory C
ORDER BY c.CertificationID
FOR XML PATH('')),1,1,'') AS CSV
GO
i just need employeeid and certificationid.but i am unable to sort it out.
You need a correlated subquery and a list of employees. The following gets the list of employees from the same table but you might have another table with this information:
SELECT e.EmployeeID,
STUFF((SELECT ',' + CAST(C.CertificationID AS VARCHAR(100))
FROM tbl_PM_EmployeeCertificationMatrixHistory C
where c.EmployeeID = e.EmployeeID
ORDER BY c.CertificationID
FOR XML PATH('')
),1, 1,'') AS CSV
from (select distinct EmployeeID
from tbl_PM_EmployeeCertificationMatrixHistory
) e;
You just need to add EmployeeID to the query as well as a WHERE and DISTINCT
SELECT DISTINCT A.EmployeeID, STUFF(
(SELECT ',' + CAST(C.CertificationID AS VARCHAR(100))
FROM tbl_PM_EmployeeCertificationMatrixHistory C
WHERE C.EmployeeID = A.EmployeeID
ORDER BY c.CertificationID
FOR XML PATH('')),1,1,'') AS CSV
FROM tbl_PM_EmployeeCertificationMatrixHistory A
GO
If you want to return only DISTINCT values in the the CSV list, add GROUP BY c.CertificationID above the ORDER BY
Related
I am searching for a solution for the SQL problem:
I have input table like this:
RId
AId
Type
76
734
TKI
76
528
NPlat
76
735
TKI
77
713
Plat
77
749
IO
77
739
TKI
77
714
NPlat
78
518
Plat
73
519
Plat
73
518
Plat
And I want this kind of output:
RId
TKI
IO
NPlat
Plat
73
518, 519
76
734, 735
528
77
739
749
714
713
78
518
I tried with PIVOT, but it's not working. Also tried with the GROUP BY and PARTITION BY together, but no success.
Can anybody have any idea to solve this?
Note: I am using Microsoft SQL Server 2016 (SP3).
Edited:
My attempts:
select
RId,
case when Type = 'TKI' then STRING_AGG(AId, ' ') END AS TKI,
case when Type = 'IO' then STRING_AGG(AId, ' ') END AS IO,
case when Type = 'NPlat' then STRING_AGG(AId, ' ') END AS NPlat,
case when Type = 'Plat' then STRING_AGG(AId, ' ') END AS Plat
from tbl_A
group by RId, Type;
STRING_AGG is not a generic function in SQL server 2016.
select
RId,
[TKI] = COUNT(*) over(partition by Type),
[IO] = COUNT(*) over(partition by Type),
[NPlat] = COUNT(*) over(partition by Type),
[Plat] = COUNT(*) over(partition by Type)
from tbl_A
group by RId, Type
order by RId;
You can concatenate the Aid into csv format first and then perform the pivot
select *
from (
select Rid, [Type],
Aid = stuff(
(select ',' + convert(varchar(10), x.Aid)
from tbl x
where x.Rid = t.Rid
and x.[Type] = t.[Type]
order by x.Aid
for xml path('')), 1, 1, '')
from tbl t
group by Rid, [Type]
) d
pivot
(
max(Aid)
for [Type] in ([TKI], [IO], [NPlat], [Plat])
) p
dbfiddle demo
Simple Use Stuff with Pivot :
SELECT RID,[TKI],[IO],[NPlat],[Plat]
FROM
(SELECT RID,TYPE,AID = STUFF((
SELECT ',' + CONVERT(VARCHAR,AID)
FROM test t
WHERE t.RID = test.RID AND t.TYPE = test.type
FOR XML PATH('')
), 1, 1, '')
FROM test
)sorce
PIVOT
(
max(AID) FOR type IN ([TKI],[IO],[NPlat],[Plat])
) AS PivotTable
I am building a pivot query inside a CTE. I have a table Table_1:
Store Week xCount
------- ---- ------
101 1 138
105 1 37
109 1 59
101 2 282
109 2 97
105 3 60
109 3 87
This is the query I used to pivot Table_1:
with CTE as
(
select
*
from
(select
store, week, xCount
from
table_1) src
pivot
(sum(xcount)
for week in ([1], [2], [3])
) piv;
)
Select *
From CTE
And this is the result I got:
| STORE | 1 | 2 | 3 |
+-------+-----+-----+-----+
| 101 | 138 | 282 | null|
| 105 | 37 | null| 60 |
| 109 | 59 | 97 | 87 |
The result is fine, but now there is one more WEEK added.
I want to develop a CTE with pivot query that will automatically generate distinct weeks and create a column on that basis.
I did some research and found a recursive CTE can be used to do this. I am new to recursive CTE, so please anyone can help me to solve this issue.
I also tried dynamic pivot query but CTE does not allow dynamic query.
Please help.
dynamic pivot doesn't work inside CTE
No, but a CTE works inside a dynamic query:
{assuming you have declared the variables used below}
SELECT #Cols = {query to get the column names in a comma-separated string}
SET #sql='
with CTE as
(
select
*
from
(select
store, week, xCount
from
table_1) src
pivot
(sum(xcount)
for week in ('+#Cols+')
) piv;
)
Select *
From CTE
'
EXEC (#sql)
Can i use recursive CTE?
No this isn't an appropriate use-case for a recursive CTE.
/* Variable to hold unique Week to be used in PIVOT clause */
DECLARE #Weeks NVARCHAR(MAX) = N''
/* Extract unique Week names with pivot formattings */
SELECT #Weeks = #Weeks + ', [' + COALESCE(week, '') + ']'
FROM (SELECT DISTINCT week FROM table_1) DT
/* Remove first comma and space */
SELECT #Weeks = LTRIM(STUFF(#Weeks , 1, 1, ''))
/* Variable to hold t-sql query */
DECLARE #CTEStatement NVARCHAR(MAX) = N''
/* Generate dynamic PIVOT query here */
SET #CTEStatement=N'
;WITH CTE as
( SELECT *
FROM
(SELECT
store
,week
,xCount
FROM
table_1) SRC
PIVOT
(SUM(xcount)
FOR week in ('+ #Weeks +')
) PIV;
)
SELECT *
FROM CTE
'
EXEC (#CTEStatement)
I have 2 tables called request and request relationship as detail below.
request
reqId regNum desc
12 111 Tomato
13 112 Carrot
14 113 Chilli
15 114 Onion
16 115 Garlic
requestRelationship
reqID relatedRequestId
12 14
12 16
13 14
13 15
What i would like to display like the following information
reqId regNum desc relateRequest
12 111 Tomato 113,115
13 112 Carrot 113,114
Currently i only have the basic query
select r.reqId, r.reqNum, r.desc, relateRequest = STUFF((select Distinct ', ' + regNum from request b where b.reqId = a.reqId FOR XML PATH (' ')), 1, 2, '')
from request r
INNER JOIN requestRelationship t WITH (NOLOCK) on r.reqID = t.reqID
order by r.reqId desc
Your STUFF essentially needs to join your request table on relatedrequestid (whereas your outer query is joining on reqID), so your whole select should look something like this:
SELECT DISTINCT R.reqID, R.regNum, R.[desc],
relateRequest = STUFF(
(SELECT DISTINCT ', ' + CAST(R2.regNum AS VARCHAR(10))
FROM request AS R2
JOIN requestRelationship AS RR2
ON RR2.relatedrequestid = R2.reqID
WHERE RR2.ReqID = RR.ReqID -- This joins to your outer query. -- You can also join on R.ReqID, doesn't make a difference.
FOR XML PATH ('')), 1, 2, '')
FROM request AS R
JOIN requestRelationship AS RR
ON RR.reqID = R.reqID;
I have the following source data (the data is an extract for a source of several hundred rows.):
ID CodeID Code
3749 69 354
3750 69 864
33721 130 XXX
33722 130 319
30446 159 XXX
30447 159 XXX
and using T-SQL I need to achieve:
CodeID Code1 Code2
69 354 864
130 XXX 319
159 XXX XXX
This doesn't seem to fit the structure for a pivot table and I have no idea how to achieve this. Does anyone have any suggestions.
You can do it with a pivot if you first assign each of the values a number using row_number()
select codeid, [1] as Code1,[2] as Code2 -- .... ,[3] etc
from
(
select codeid, code, ROW_NUMBER() over (partition by codeid order by id) rn
from yourtable
) p
pivot (max(code) for rn in ([1],[2])) p2 --, [3]... etc
I have a table named ComplimentTransactAssign_tbl. In this table there are a lot of duplicate entries. Table structure is like this:
TransactID Cmplid
-
32 16
105 17
105 17
290 12
32 16
290 12
I find out my duplicate records like this:
select TransactID from ComplimentTransactAssign_tbl
group by TransactID having count(*) >1 order by TransactID
I want to delete duplicate records. After deleting I want to get output like this:
TransactID Cmplid
-
32 16
105 17
290 12
;WITH MyCTE AS
(
SELECT TransactID ,
Cmplid,
ROW_NUMBER() OVER(PARTITION BY TransactID ORDER BY TransactID) AS row_num
FROM ComplimentTransactAssign_tbl cta
)
DELETE FROM MyCTE
WHERE row_num <> 1
SQL Fiddle Example