PIVOT/UNPIVOT more than one column












0















Is there a way to use SQL Pivot/Unpivot to produce the output under Converted below from the table Original?



enter image description here










share|improve this question




















  • 2





    Please show your code attempt.

    – Dale Burrell
    Jan 2 at 4:05
















0















Is there a way to use SQL Pivot/Unpivot to produce the output under Converted below from the table Original?



enter image description here










share|improve this question




















  • 2





    Please show your code attempt.

    – Dale Burrell
    Jan 2 at 4:05














0












0








0


1






Is there a way to use SQL Pivot/Unpivot to produce the output under Converted below from the table Original?



enter image description here










share|improve this question
















Is there a way to use SQL Pivot/Unpivot to produce the output under Converted below from the table Original?



enter image description here







sql sql-server tsql pivot unpivot






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 16:02









Andrea

7,761144954




7,761144954










asked Jan 2 at 4:01









VTISCHUKVTISCHUK

174




174








  • 2





    Please show your code attempt.

    – Dale Burrell
    Jan 2 at 4:05














  • 2





    Please show your code attempt.

    – Dale Burrell
    Jan 2 at 4:05








2




2





Please show your code attempt.

– Dale Burrell
Jan 2 at 4:05





Please show your code attempt.

– Dale Burrell
Jan 2 at 4:05












2 Answers
2






active

oldest

votes


















0














No, there is no variation of PIVOT/UNPIVOT that will let you create that first row in your "converted" output, with the id in one column and the values of type for each of the other columns.



That's going to require some custom select to create the first row, and then UNION with an UNPIVOT to create the rest of the rows.



Since no aggregation is being performed, I don't know why you want to do this in SQL. Personally I would do this in the presentation layer.






share|improve this answer































    0














    You can achieve the "converted" layout with dynamic sql, but be aware of performance and security problems of this approach.



    Moreover as said by Tab Alleman in his answer this is clearly a work for the presentation layer.



    If you still want to do this in SQL Server, here is a possible solution:



    CREATE TABLE [dbo].[Test] (
    [id] int
    ,[type] varchar(50)
    ,NBR varchar(50)
    ,c1_pos int
    ,c1_neg int
    ,c2_pos int
    ,c2_neg int )

    INSERT INTO [dbo].[Test]
    values
    (8375, 'Type #1', 'P #1', 1, 0, 0, 0)
    ,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
    ,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
    ,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
    ,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)

    --this variable holds the value that will become the header of the first column
    declare @first_column_header nvarchar(10)
    --this variable holds all the dates that will become column names
    declare @headers nvarchar(max)=''
    --this variable contains the TSQL dinamically generated
    declare @sql nvarchar(max)=''

    SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
    select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
    set @headers = RIGHT(@headers, len(@headers) - 2)

    set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
    set @sql = @sql + 'from '
    set @sql = @sql + '( '
    set @sql = @sql + ' select [type], col, val, ord '
    set @sql = @sql + ' from [dbo].[Test] '
    set @sql = @sql + ' CROSS APPLY ('
    set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
    set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
    set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
    set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
    set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
    set @sql = @sql + ' )CS (col, val, ord) '
    set @sql = @sql + ') src '
    set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
    set @sql = @sql + 'order by ord'

    exec(@sql)


    Result:



    enter image description here






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54001053%2fpivot-unpivot-more-than-one-column%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      No, there is no variation of PIVOT/UNPIVOT that will let you create that first row in your "converted" output, with the id in one column and the values of type for each of the other columns.



      That's going to require some custom select to create the first row, and then UNION with an UNPIVOT to create the rest of the rows.



      Since no aggregation is being performed, I don't know why you want to do this in SQL. Personally I would do this in the presentation layer.






      share|improve this answer




























        0














        No, there is no variation of PIVOT/UNPIVOT that will let you create that first row in your "converted" output, with the id in one column and the values of type for each of the other columns.



        That's going to require some custom select to create the first row, and then UNION with an UNPIVOT to create the rest of the rows.



        Since no aggregation is being performed, I don't know why you want to do this in SQL. Personally I would do this in the presentation layer.






        share|improve this answer


























          0












          0








          0







          No, there is no variation of PIVOT/UNPIVOT that will let you create that first row in your "converted" output, with the id in one column and the values of type for each of the other columns.



          That's going to require some custom select to create the first row, and then UNION with an UNPIVOT to create the rest of the rows.



          Since no aggregation is being performed, I don't know why you want to do this in SQL. Personally I would do this in the presentation layer.






          share|improve this answer













          No, there is no variation of PIVOT/UNPIVOT that will let you create that first row in your "converted" output, with the id in one column and the values of type for each of the other columns.



          That's going to require some custom select to create the first row, and then UNION with an UNPIVOT to create the rest of the rows.



          Since no aggregation is being performed, I don't know why you want to do this in SQL. Personally I would do this in the presentation layer.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 2 at 14:54









          Tab AllemanTab Alleman

          27.1k62442




          27.1k62442

























              0














              You can achieve the "converted" layout with dynamic sql, but be aware of performance and security problems of this approach.



              Moreover as said by Tab Alleman in his answer this is clearly a work for the presentation layer.



              If you still want to do this in SQL Server, here is a possible solution:



              CREATE TABLE [dbo].[Test] (
              [id] int
              ,[type] varchar(50)
              ,NBR varchar(50)
              ,c1_pos int
              ,c1_neg int
              ,c2_pos int
              ,c2_neg int )

              INSERT INTO [dbo].[Test]
              values
              (8375, 'Type #1', 'P #1', 1, 0, 0, 0)
              ,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
              ,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
              ,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
              ,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)

              --this variable holds the value that will become the header of the first column
              declare @first_column_header nvarchar(10)
              --this variable holds all the dates that will become column names
              declare @headers nvarchar(max)=''
              --this variable contains the TSQL dinamically generated
              declare @sql nvarchar(max)=''

              SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
              select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
              set @headers = RIGHT(@headers, len(@headers) - 2)

              set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
              set @sql = @sql + 'from '
              set @sql = @sql + '( '
              set @sql = @sql + ' select [type], col, val, ord '
              set @sql = @sql + ' from [dbo].[Test] '
              set @sql = @sql + ' CROSS APPLY ('
              set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
              set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
              set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
              set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
              set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
              set @sql = @sql + ' )CS (col, val, ord) '
              set @sql = @sql + ') src '
              set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
              set @sql = @sql + 'order by ord'

              exec(@sql)


              Result:



              enter image description here






              share|improve this answer




























                0














                You can achieve the "converted" layout with dynamic sql, but be aware of performance and security problems of this approach.



                Moreover as said by Tab Alleman in his answer this is clearly a work for the presentation layer.



                If you still want to do this in SQL Server, here is a possible solution:



                CREATE TABLE [dbo].[Test] (
                [id] int
                ,[type] varchar(50)
                ,NBR varchar(50)
                ,c1_pos int
                ,c1_neg int
                ,c2_pos int
                ,c2_neg int )

                INSERT INTO [dbo].[Test]
                values
                (8375, 'Type #1', 'P #1', 1, 0, 0, 0)
                ,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
                ,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
                ,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
                ,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)

                --this variable holds the value that will become the header of the first column
                declare @first_column_header nvarchar(10)
                --this variable holds all the dates that will become column names
                declare @headers nvarchar(max)=''
                --this variable contains the TSQL dinamically generated
                declare @sql nvarchar(max)=''

                SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
                select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
                set @headers = RIGHT(@headers, len(@headers) - 2)

                set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
                set @sql = @sql + 'from '
                set @sql = @sql + '( '
                set @sql = @sql + ' select [type], col, val, ord '
                set @sql = @sql + ' from [dbo].[Test] '
                set @sql = @sql + ' CROSS APPLY ('
                set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
                set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
                set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
                set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
                set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
                set @sql = @sql + ' )CS (col, val, ord) '
                set @sql = @sql + ') src '
                set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
                set @sql = @sql + 'order by ord'

                exec(@sql)


                Result:



                enter image description here






                share|improve this answer


























                  0












                  0








                  0







                  You can achieve the "converted" layout with dynamic sql, but be aware of performance and security problems of this approach.



                  Moreover as said by Tab Alleman in his answer this is clearly a work for the presentation layer.



                  If you still want to do this in SQL Server, here is a possible solution:



                  CREATE TABLE [dbo].[Test] (
                  [id] int
                  ,[type] varchar(50)
                  ,NBR varchar(50)
                  ,c1_pos int
                  ,c1_neg int
                  ,c2_pos int
                  ,c2_neg int )

                  INSERT INTO [dbo].[Test]
                  values
                  (8375, 'Type #1', 'P #1', 1, 0, 0, 0)
                  ,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
                  ,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
                  ,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
                  ,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)

                  --this variable holds the value that will become the header of the first column
                  declare @first_column_header nvarchar(10)
                  --this variable holds all the dates that will become column names
                  declare @headers nvarchar(max)=''
                  --this variable contains the TSQL dinamically generated
                  declare @sql nvarchar(max)=''

                  SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
                  select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
                  set @headers = RIGHT(@headers, len(@headers) - 2)

                  set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
                  set @sql = @sql + 'from '
                  set @sql = @sql + '( '
                  set @sql = @sql + ' select [type], col, val, ord '
                  set @sql = @sql + ' from [dbo].[Test] '
                  set @sql = @sql + ' CROSS APPLY ('
                  set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
                  set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
                  set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
                  set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
                  set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
                  set @sql = @sql + ' )CS (col, val, ord) '
                  set @sql = @sql + ') src '
                  set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
                  set @sql = @sql + 'order by ord'

                  exec(@sql)


                  Result:



                  enter image description here






                  share|improve this answer













                  You can achieve the "converted" layout with dynamic sql, but be aware of performance and security problems of this approach.



                  Moreover as said by Tab Alleman in his answer this is clearly a work for the presentation layer.



                  If you still want to do this in SQL Server, here is a possible solution:



                  CREATE TABLE [dbo].[Test] (
                  [id] int
                  ,[type] varchar(50)
                  ,NBR varchar(50)
                  ,c1_pos int
                  ,c1_neg int
                  ,c2_pos int
                  ,c2_neg int )

                  INSERT INTO [dbo].[Test]
                  values
                  (8375, 'Type #1', 'P #1', 1, 0, 0, 0)
                  ,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
                  ,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
                  ,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
                  ,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)

                  --this variable holds the value that will become the header of the first column
                  declare @first_column_header nvarchar(10)
                  --this variable holds all the dates that will become column names
                  declare @headers nvarchar(max)=''
                  --this variable contains the TSQL dinamically generated
                  declare @sql nvarchar(max)=''

                  SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
                  select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
                  set @headers = RIGHT(@headers, len(@headers) - 2)

                  set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
                  set @sql = @sql + 'from '
                  set @sql = @sql + '( '
                  set @sql = @sql + ' select [type], col, val, ord '
                  set @sql = @sql + ' from [dbo].[Test] '
                  set @sql = @sql + ' CROSS APPLY ('
                  set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
                  set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
                  set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
                  set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
                  set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
                  set @sql = @sql + ' )CS (col, val, ord) '
                  set @sql = @sql + ') src '
                  set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
                  set @sql = @sql + 'order by ord'

                  exec(@sql)


                  Result:



                  enter image description here







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 4 at 15:58









                  AndreaAndrea

                  7,761144954




                  7,761144954






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54001053%2fpivot-unpivot-more-than-one-column%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      How to fix TextFormField cause rebuild widget in Flutter

                      in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith