Need some help solving a SQL problem with grouping











up vote
2
down vote

favorite












I'll cut straight to the chase. I currently have reduced a larger table to one such as the following:



 Key    Group    Data1    Data2    Data3
===== ======= ======= ======= =======
AAA A 1 0 0
ASD A 1 1 0
FSD A 1 0 1
BAS A 1 1 1
CDR B 1 1 1
KLW B 1 0 1


Here is the code to create and populate it:



CREATE TABLE #DataGroups
(
[Key] VARCHAR(25),
[Group] VARCHAR(25),
[Data1] BIT,
[Data2] BIT,
[Data3] BIT
)

INSERT INTO #DataGroups VALUES
('AAA', 'A', 1, 0, 0),
('ASD', 'A', 1, 1, 0),
('FSD', 'A', 1, 0, 1),
('BAS', 'A', 1, 1, 1),
('CDR', 'B', 1, 1, 1),
('KLW', 'B', 1, 0, 1)


Constraints are as follows:




  • 'Key' is unique

  • ('Group', 'Data1', 'Data2', 'Data3') is unique

  • 'Data1' will always be 1 (however I don't know if this is pertinent to the solution, we can assume that it may not always be 1)


What I need to do is formulate a query that rearranges the data in the following manner:



 Group     Data1     Data12    Data13    Data123
======= ======== ========= ======== =========
A AAA ASD FSD BAS
B NULL NULL KLW CDR


As per this table, I need to fetch the Key based on the Data values for each group. So for the Data 1 column, I need to fetch the Key in the Group where the Data1 = 1, Data2 = 0 and Data3 = 0. Let me know if I should clarify if this doesn't make sense.



I'm not too experienced with SQL, so I'd prefer as clean as a solution as possible. I know that since I'll be converting my row data to columns, I will most likely need to use PIVOT, but I'm not entirely sure. Even a little help with what type of functions / aggregates I'll need to use to get this figured out would be greatly appreciated.



Apologies as I've tried coming up with my own solution to try and get started using PIVOT, but I can't seem to work one out even close to how I want it.










share|improve this question


























    up vote
    2
    down vote

    favorite












    I'll cut straight to the chase. I currently have reduced a larger table to one such as the following:



     Key    Group    Data1    Data2    Data3
    ===== ======= ======= ======= =======
    AAA A 1 0 0
    ASD A 1 1 0
    FSD A 1 0 1
    BAS A 1 1 1
    CDR B 1 1 1
    KLW B 1 0 1


    Here is the code to create and populate it:



    CREATE TABLE #DataGroups
    (
    [Key] VARCHAR(25),
    [Group] VARCHAR(25),
    [Data1] BIT,
    [Data2] BIT,
    [Data3] BIT
    )

    INSERT INTO #DataGroups VALUES
    ('AAA', 'A', 1, 0, 0),
    ('ASD', 'A', 1, 1, 0),
    ('FSD', 'A', 1, 0, 1),
    ('BAS', 'A', 1, 1, 1),
    ('CDR', 'B', 1, 1, 1),
    ('KLW', 'B', 1, 0, 1)


    Constraints are as follows:




    • 'Key' is unique

    • ('Group', 'Data1', 'Data2', 'Data3') is unique

    • 'Data1' will always be 1 (however I don't know if this is pertinent to the solution, we can assume that it may not always be 1)


    What I need to do is formulate a query that rearranges the data in the following manner:



     Group     Data1     Data12    Data13    Data123
    ======= ======== ========= ======== =========
    A AAA ASD FSD BAS
    B NULL NULL KLW CDR


    As per this table, I need to fetch the Key based on the Data values for each group. So for the Data 1 column, I need to fetch the Key in the Group where the Data1 = 1, Data2 = 0 and Data3 = 0. Let me know if I should clarify if this doesn't make sense.



    I'm not too experienced with SQL, so I'd prefer as clean as a solution as possible. I know that since I'll be converting my row data to columns, I will most likely need to use PIVOT, but I'm not entirely sure. Even a little help with what type of functions / aggregates I'll need to use to get this figured out would be greatly appreciated.



    Apologies as I've tried coming up with my own solution to try and get started using PIVOT, but I can't seem to work one out even close to how I want it.










    share|improve this question
























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I'll cut straight to the chase. I currently have reduced a larger table to one such as the following:



       Key    Group    Data1    Data2    Data3
      ===== ======= ======= ======= =======
      AAA A 1 0 0
      ASD A 1 1 0
      FSD A 1 0 1
      BAS A 1 1 1
      CDR B 1 1 1
      KLW B 1 0 1


      Here is the code to create and populate it:



      CREATE TABLE #DataGroups
      (
      [Key] VARCHAR(25),
      [Group] VARCHAR(25),
      [Data1] BIT,
      [Data2] BIT,
      [Data3] BIT
      )

      INSERT INTO #DataGroups VALUES
      ('AAA', 'A', 1, 0, 0),
      ('ASD', 'A', 1, 1, 0),
      ('FSD', 'A', 1, 0, 1),
      ('BAS', 'A', 1, 1, 1),
      ('CDR', 'B', 1, 1, 1),
      ('KLW', 'B', 1, 0, 1)


      Constraints are as follows:




      • 'Key' is unique

      • ('Group', 'Data1', 'Data2', 'Data3') is unique

      • 'Data1' will always be 1 (however I don't know if this is pertinent to the solution, we can assume that it may not always be 1)


      What I need to do is formulate a query that rearranges the data in the following manner:



       Group     Data1     Data12    Data13    Data123
      ======= ======== ========= ======== =========
      A AAA ASD FSD BAS
      B NULL NULL KLW CDR


      As per this table, I need to fetch the Key based on the Data values for each group. So for the Data 1 column, I need to fetch the Key in the Group where the Data1 = 1, Data2 = 0 and Data3 = 0. Let me know if I should clarify if this doesn't make sense.



      I'm not too experienced with SQL, so I'd prefer as clean as a solution as possible. I know that since I'll be converting my row data to columns, I will most likely need to use PIVOT, but I'm not entirely sure. Even a little help with what type of functions / aggregates I'll need to use to get this figured out would be greatly appreciated.



      Apologies as I've tried coming up with my own solution to try and get started using PIVOT, but I can't seem to work one out even close to how I want it.










      share|improve this question













      I'll cut straight to the chase. I currently have reduced a larger table to one such as the following:



       Key    Group    Data1    Data2    Data3
      ===== ======= ======= ======= =======
      AAA A 1 0 0
      ASD A 1 1 0
      FSD A 1 0 1
      BAS A 1 1 1
      CDR B 1 1 1
      KLW B 1 0 1


      Here is the code to create and populate it:



      CREATE TABLE #DataGroups
      (
      [Key] VARCHAR(25),
      [Group] VARCHAR(25),
      [Data1] BIT,
      [Data2] BIT,
      [Data3] BIT
      )

      INSERT INTO #DataGroups VALUES
      ('AAA', 'A', 1, 0, 0),
      ('ASD', 'A', 1, 1, 0),
      ('FSD', 'A', 1, 0, 1),
      ('BAS', 'A', 1, 1, 1),
      ('CDR', 'B', 1, 1, 1),
      ('KLW', 'B', 1, 0, 1)


      Constraints are as follows:




      • 'Key' is unique

      • ('Group', 'Data1', 'Data2', 'Data3') is unique

      • 'Data1' will always be 1 (however I don't know if this is pertinent to the solution, we can assume that it may not always be 1)


      What I need to do is formulate a query that rearranges the data in the following manner:



       Group     Data1     Data12    Data13    Data123
      ======= ======== ========= ======== =========
      A AAA ASD FSD BAS
      B NULL NULL KLW CDR


      As per this table, I need to fetch the Key based on the Data values for each group. So for the Data 1 column, I need to fetch the Key in the Group where the Data1 = 1, Data2 = 0 and Data3 = 0. Let me know if I should clarify if this doesn't make sense.



      I'm not too experienced with SQL, so I'd prefer as clean as a solution as possible. I know that since I'll be converting my row data to columns, I will most likely need to use PIVOT, but I'm not entirely sure. Even a little help with what type of functions / aggregates I'll need to use to get this figured out would be greatly appreciated.



      Apologies as I've tried coming up with my own solution to try and get started using PIVOT, but I can't seem to work one out even close to how I want it.







      sql sql-server tsql






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 21 at 14:45









      Jon Warren

      137112




      137112
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          You seem to want something like this:



          select group,
          max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
          max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
          max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
          max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
          from #DataGroups dg
          group by group





          share|improve this answer





















          • Wow, this ended up being a lot simpler than I had imagined. Thank you!
            – Jon Warren
            Nov 21 at 15:15


















          up vote
          1
          down vote













          I would use Gordon's solution. But for fun, here's the maths/pivot based solution instead, based on the fact we can combine the bits to form a number:



          declare @DataGroups table
          (
          [Key] VARCHAR(25),
          [Group] VARCHAR(25),
          [Data1] BIT,
          [Data2] BIT,
          [Data3] BIT
          )

          INSERT INTO @DataGroups VALUES
          ('AAA', 'A', 1, 0, 0),
          ('ASD', 'A', 1, 1, 0),
          ('FSD', 'A', 1, 0, 1),
          ('BAS', 'A', 1, 1, 1),
          ('CDR', 'B', 1, 1, 1),
          ('KLW', 'B', 1, 0, 1)

          ;With Basics as (
          select
          [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
          from
          @DataGroups dg
          )
          select
          [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
          from
          Basics
          pivot
          (MAX([Key]) for Total in ([1],[3],[5],[7])) v


          Note, we have to use a subquery/CTE to remove the Data1, etc columns from the result set before we pivot1, because otherwise they form part of the implicit set of grouping columns for the pivot and we don't collapse any rows. Change the select in Basics to use *,Data1 + (2 * data2) + (4 * data3) as Total to see what that looks like.



          Result:



          Group    Data1    Data12   Data13   Data123
          -------- -------- -------- -------- ---------
          A AAA ASD FSD BAS
          B NULL NULL KLW CDR




          1I'm always griping about this so decided it was time to add a feedback issue for it to see if SQL Server could be improved.






          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',
            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%2f53414559%2fneed-some-help-solving-a-sql-problem-with-grouping%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








            up vote
            2
            down vote



            accepted










            You seem to want something like this:



            select group,
            max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
            max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
            max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
            max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
            from #DataGroups dg
            group by group





            share|improve this answer





















            • Wow, this ended up being a lot simpler than I had imagined. Thank you!
              – Jon Warren
              Nov 21 at 15:15















            up vote
            2
            down vote



            accepted










            You seem to want something like this:



            select group,
            max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
            max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
            max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
            max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
            from #DataGroups dg
            group by group





            share|improve this answer





















            • Wow, this ended up being a lot simpler than I had imagined. Thank you!
              – Jon Warren
              Nov 21 at 15:15













            up vote
            2
            down vote



            accepted







            up vote
            2
            down vote



            accepted






            You seem to want something like this:



            select group,
            max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
            max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
            max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
            max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
            from #DataGroups dg
            group by group





            share|improve this answer












            You seem to want something like this:



            select group,
            max(case when data1 = 1 and data2 = 0 and data3 = 0 then key end) as data1,
            max(case when data1 = 1 and data2 = 1 and data3 = 0 then key end) as data12,
            max(case when data1 = 1 and data2 = 0 and data3 = 1 then key end) as data13,
            max(case when data1 = 1 and data2 = 1 and data3 = 1 then key end) as data123
            from #DataGroups dg
            group by group






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 21 at 14:55









            Gordon Linoff

            750k34285391




            750k34285391












            • Wow, this ended up being a lot simpler than I had imagined. Thank you!
              – Jon Warren
              Nov 21 at 15:15


















            • Wow, this ended up being a lot simpler than I had imagined. Thank you!
              – Jon Warren
              Nov 21 at 15:15
















            Wow, this ended up being a lot simpler than I had imagined. Thank you!
            – Jon Warren
            Nov 21 at 15:15




            Wow, this ended up being a lot simpler than I had imagined. Thank you!
            – Jon Warren
            Nov 21 at 15:15












            up vote
            1
            down vote













            I would use Gordon's solution. But for fun, here's the maths/pivot based solution instead, based on the fact we can combine the bits to form a number:



            declare @DataGroups table
            (
            [Key] VARCHAR(25),
            [Group] VARCHAR(25),
            [Data1] BIT,
            [Data2] BIT,
            [Data3] BIT
            )

            INSERT INTO @DataGroups VALUES
            ('AAA', 'A', 1, 0, 0),
            ('ASD', 'A', 1, 1, 0),
            ('FSD', 'A', 1, 0, 1),
            ('BAS', 'A', 1, 1, 1),
            ('CDR', 'B', 1, 1, 1),
            ('KLW', 'B', 1, 0, 1)

            ;With Basics as (
            select
            [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
            from
            @DataGroups dg
            )
            select
            [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
            from
            Basics
            pivot
            (MAX([Key]) for Total in ([1],[3],[5],[7])) v


            Note, we have to use a subquery/CTE to remove the Data1, etc columns from the result set before we pivot1, because otherwise they form part of the implicit set of grouping columns for the pivot and we don't collapse any rows. Change the select in Basics to use *,Data1 + (2 * data2) + (4 * data3) as Total to see what that looks like.



            Result:



            Group    Data1    Data12   Data13   Data123
            -------- -------- -------- -------- ---------
            A AAA ASD FSD BAS
            B NULL NULL KLW CDR




            1I'm always griping about this so decided it was time to add a feedback issue for it to see if SQL Server could be improved.






            share|improve this answer



























              up vote
              1
              down vote













              I would use Gordon's solution. But for fun, here's the maths/pivot based solution instead, based on the fact we can combine the bits to form a number:



              declare @DataGroups table
              (
              [Key] VARCHAR(25),
              [Group] VARCHAR(25),
              [Data1] BIT,
              [Data2] BIT,
              [Data3] BIT
              )

              INSERT INTO @DataGroups VALUES
              ('AAA', 'A', 1, 0, 0),
              ('ASD', 'A', 1, 1, 0),
              ('FSD', 'A', 1, 0, 1),
              ('BAS', 'A', 1, 1, 1),
              ('CDR', 'B', 1, 1, 1),
              ('KLW', 'B', 1, 0, 1)

              ;With Basics as (
              select
              [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
              from
              @DataGroups dg
              )
              select
              [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
              from
              Basics
              pivot
              (MAX([Key]) for Total in ([1],[3],[5],[7])) v


              Note, we have to use a subquery/CTE to remove the Data1, etc columns from the result set before we pivot1, because otherwise they form part of the implicit set of grouping columns for the pivot and we don't collapse any rows. Change the select in Basics to use *,Data1 + (2 * data2) + (4 * data3) as Total to see what that looks like.



              Result:



              Group    Data1    Data12   Data13   Data123
              -------- -------- -------- -------- ---------
              A AAA ASD FSD BAS
              B NULL NULL KLW CDR




              1I'm always griping about this so decided it was time to add a feedback issue for it to see if SQL Server could be improved.






              share|improve this answer

























                up vote
                1
                down vote










                up vote
                1
                down vote









                I would use Gordon's solution. But for fun, here's the maths/pivot based solution instead, based on the fact we can combine the bits to form a number:



                declare @DataGroups table
                (
                [Key] VARCHAR(25),
                [Group] VARCHAR(25),
                [Data1] BIT,
                [Data2] BIT,
                [Data3] BIT
                )

                INSERT INTO @DataGroups VALUES
                ('AAA', 'A', 1, 0, 0),
                ('ASD', 'A', 1, 1, 0),
                ('FSD', 'A', 1, 0, 1),
                ('BAS', 'A', 1, 1, 1),
                ('CDR', 'B', 1, 1, 1),
                ('KLW', 'B', 1, 0, 1)

                ;With Basics as (
                select
                [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
                from
                @DataGroups dg
                )
                select
                [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
                from
                Basics
                pivot
                (MAX([Key]) for Total in ([1],[3],[5],[7])) v


                Note, we have to use a subquery/CTE to remove the Data1, etc columns from the result set before we pivot1, because otherwise they form part of the implicit set of grouping columns for the pivot and we don't collapse any rows. Change the select in Basics to use *,Data1 + (2 * data2) + (4 * data3) as Total to see what that looks like.



                Result:



                Group    Data1    Data12   Data13   Data123
                -------- -------- -------- -------- ---------
                A AAA ASD FSD BAS
                B NULL NULL KLW CDR




                1I'm always griping about this so decided it was time to add a feedback issue for it to see if SQL Server could be improved.






                share|improve this answer














                I would use Gordon's solution. But for fun, here's the maths/pivot based solution instead, based on the fact we can combine the bits to form a number:



                declare @DataGroups table
                (
                [Key] VARCHAR(25),
                [Group] VARCHAR(25),
                [Data1] BIT,
                [Data2] BIT,
                [Data3] BIT
                )

                INSERT INTO @DataGroups VALUES
                ('AAA', 'A', 1, 0, 0),
                ('ASD', 'A', 1, 1, 0),
                ('FSD', 'A', 1, 0, 1),
                ('BAS', 'A', 1, 1, 1),
                ('CDR', 'B', 1, 1, 1),
                ('KLW', 'B', 1, 0, 1)

                ;With Basics as (
                select
                [Group],[Key],Data1 + (2 * data2) + (4 * data3) as Total
                from
                @DataGroups dg
                )
                select
                [Group],[1] as Data1,[3] as Data12,[5] as Data13,[7] as Data123
                from
                Basics
                pivot
                (MAX([Key]) for Total in ([1],[3],[5],[7])) v


                Note, we have to use a subquery/CTE to remove the Data1, etc columns from the result set before we pivot1, because otherwise they form part of the implicit set of grouping columns for the pivot and we don't collapse any rows. Change the select in Basics to use *,Data1 + (2 * data2) + (4 * data3) as Total to see what that looks like.



                Result:



                Group    Data1    Data12   Data13   Data123
                -------- -------- -------- -------- ---------
                A AAA ASD FSD BAS
                B NULL NULL KLW CDR




                1I'm always griping about this so decided it was time to add a feedback issue for it to see if SQL Server could be improved.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 21 at 15:32

























                answered Nov 21 at 15:08









                Damien_The_Unbeliever

                191k17243329




                191k17243329






























                    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.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • 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%2f53414559%2fneed-some-help-solving-a-sql-problem-with-grouping%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

                    Berounka

                    Sphinx de Gizeh

                    Different font size/position of beamer's navigation symbols template's content depending on regular/plain...