Reputation: 345
I have a table.
Item | ID
--------------
1-A | 213
2-B | 432
3-C | 267
3-C | 879
3-C | 467
I use pivot.
Select * from (
Select ID,Item
From data1
)R
Pivot (
Max(ID) For Item
in
([1-A],[2-B],[3-C])
)as pvt
But I can only get one value.
1-A | 2-B | 3-C
-----------------
213 | 453 | 467
How can I get all the values of 3-C, I hope I can get this result.
1-A | 2-B | 3-C | 3-C | 3-C
---------------------------
213 | 453 | 267 | 879 | 467
But 3-C, there may be one or more, I cannot control how many will appear.
Hope to help answer, thank you.
Upvotes: 0
Views: 83
Reputation: 1269873
An alternative method would be to put the results in a single column for 3-C
values, using string_agg()
:
select string_agg(case when item = '[1-A]' then id end, ',') within group (order by id) as id_1_a,
string_agg(case when item = '[2-B]' then id end, ',') within group (order by id) as id_2_b,
string_agg(case when item = '[3-C]' then id end, ',') within group (order by id) as id_3_c
from data1;
This is not the exact result set you specify, but it might accomplish what you need.
Upvotes: 0
Reputation: 95557
The real problem here is that you have an indeterminable number of rows. This means you need dynamic SQL, The next problem is that you don't have unique values to pivot on, so we need to get inventive with ROW_NUMBER
as well. This gives this, which is not particularly pretty, but "works".
CREATE TABLE dbo.YourTable (Item char(3),
ID int);
INSERT INTO dbo.YourTable (Item,
ID)
VALUES('1-A',213),
('2-B',432),
('3-C',267),
('3-C',879),
('3-C',467);
GO
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE @Delimiter nvarchar(30) = N',' + @CRLF + N' ';
WITH RNs AS(
SELECT Item,
ID,
ROW_NUMBER() OVER (ORDER BY Item) AS RN
FROM dbo.YourTable)
SELECT @SQL = N'WITH RNs AS(' + @CRLF +
N' SELECT Item,' + @CRLF +
N' ID,' + @CRLF +
N' ROW_NUMBER() OVER (ORDER BY Item) AS RN' + @CRLF +
N' FROM dbo.YourTable)' + @CRLF +
N'SELECT ' +
STRING_AGG(CONCAT(N'MAX(CASE WHEN Item = ',QUOTENAME(R.Item,''''),N' AND RN = ',R.RN,N' THEN R.ID END) AS ',QUOTENAME(R.Item)),@Delimiter) WITHIN GROUP (ORDER BY R.Item, R.RN) + @CRLF +
N'FROM RNs R;'
FROM RNs R;
PRINT @SQL;
EXEC sys.sp_executesql @SQL;
GO
DROP TABLE dbo.YourTable;
I have assumed you are using a recent version of SQL Server. If not, you will need to replace STRING_AGG
with the older FOR XML PATH
method.
Upvotes: 3
Reputation: 24763
You will need to use Dynamic SQL
since you have an unknown number of columns. The query is form dynamically and use sp_executesql
to execute the query
Looks like you wanted a distinct value of Item
& ID
combination, so I use GROUP BY Item, ID
here.
declare @sql nvarchar(max)
SELECT @sql = isnull(@sql + ',', 'SELECT ')
+ CONVERT(VARCHAR(10), ID) + ' AS ' + QUOTENAME(Item)
FROM data1
GROUP BY Item, ID
ORDER BY Item, ID
-- PRINT @sql
exec sp_executesql @sql
Example : dbfiddle
Upvotes: 0