0

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.

4
  • How many rows could there be, is it always 5? What determines the order of said rows when they have the same value for Item (as it is clearly not ID) or does the order not matter? Commented Oct 5, 2020 at 9:25
  • Currently only 3-C will have multiple, at least one, and at most many,That is, there will be multiple 3-C situations Commented Oct 5, 2020 at 10:02
  • "At most many"? Many isn't a number. Does that mean that there is an indeterminable about of rows? What about the rest I asked in my comment..? Commented Oct 5, 2020 at 10:06
  • Yes,an indeterminable of rows,and order not matter.If it is possible,, I hope it will be shown according to my results Commented Oct 5, 2020 at 10:12

3 Answers 3

3

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.

DB<>Fiddle

Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

You appar to have lost a row; you have 5 columns but 6 rows in the fiddle.
2 of the rows are identical. I doubt OP wanted duplicate Item & ID value. It is intentionally added to illustrate that.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.