1

I have a table like in SQL like:

Id flag_0 doc date
1  1      1   d1
1  1      2   d2
1  1      3   d3
2  0      1   d4
2  0      2   d5

I want a query to reach the following table:

Id flag_0 doc_1 doc_2 doc_3
1  1      d1     d2   d3 
2  0      d4     d5   nan (or missing)

1 Answers1

2

You can pivot the given table in generalised sql query as in this demo

SELECT 
    Id, 
    flag_0,
    MAX(CASE WHEN doc = 1 THEN date END) AS doc_1,
    MAX(CASE WHEN doc = 2 THEN date END) AS doc_2,
    MAX(CASE WHEN doc = 3 THEN date END) AS doc_3
FROM 
    MyTable
GROUP BY 
    Id, flag_0
Order by Id;

This shall give you the output as :

Id  flag_0  doc_1   doc_2   doc_3
1   True    d1      d2      d3
2   False   d4      d5      null

if the date value do not exist; you can mark it as nan or missing in MYSQL using IFNULL function as in this demo :

SELECT 
    Id, 
    flag_0,
    IFNULL(MAX(CASE WHEN doc = 1 THEN date END), 'nan') AS doc_1,
    IFNULL(MAX(CASE WHEN doc = 2 THEN date END), 'nan') AS doc_2,
    IFNULL(MAX(CASE WHEN doc = 3 THEN date END), 'nan') AS doc_3
FROM 
    MyTable
GROUP BY 
    Id, flag_0;

Output :

Id  flag_0  doc_1   doc_2   doc_3
 1  True    d1      d2      d3
 2  False   d4      d5      nan

If you are using SQL-Server; You can write the query using PIVOT operator as in this demo :

SELECT 
    Id, 
    flag_0, 
    ISNULL([1], 'nan') AS doc_1, 
    ISNULL([2], 'nan') AS doc_2, 
    ISNULL([3], 'nan') AS doc_3
FROM 
    (SELECT Id, flag_0, doc, date FROM MyTable) AS SourceTable
PIVOT 
(
    MAX(date) FOR doc IN ([1], [2], [3])
) AS PivotTable
Order by Id;

Output :

Id  flag_0  doc_1   doc_2   doc_3
 1  True    d1      d2      d3
 2  False   d4      d5      nan

is there a way to create the columns doc automatically. I have about 40 different docs, My table has over 1M rows

The below solution shall work for you. Here is a demo.

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT distinct ',' + QUOTENAME(doc) 
                    from MyTable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @query = 'SELECT Id, flag_0, ' + @cols + ' from 
            (
                select Id, flag_0, doc, date
                from MyTable
            ) x
            pivot 
            (
                MAX(date)
                for doc in (' + @cols + ')
            ) p 
            order by Id'

EXECUTE(@query);
Tushar
  • 3,527
  • 9
  • 27
  • 49
  • 1
    Thanks for the help, but is there a way to create the columns doc automatically. I have about 40 different docs – Fernando Quintino Mar 30 '23 at 12:55
  • 1
    I am using SQL server Management Studio. My table has over 1M rows. The database if from my company, and I can share just part of the table , but I dont know how to do it here. – Fernando Quintino Mar 30 '23 at 13:19