Select multiple count queries in single query

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I currently have 6 very similar queries that I'm trying to increase performance on by making them all subqueries in 1 query. I'm not sure what is better performance wise, keeping them 6 separate queries, 1 query with 6 subqueries (as shown below), or some other method that I'm unfamiliar with.



SELECT 
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName) AS total,
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
(SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_C BETWEEN 100 AND 199) AS code_c_count
FROM table_one
WHERE ROWNUM=1






share|improve this question

























    up vote
    1
    down vote

    favorite












    I currently have 6 very similar queries that I'm trying to increase performance on by making them all subqueries in 1 query. I'm not sure what is better performance wise, keeping them 6 separate queries, 1 query with 6 subqueries (as shown below), or some other method that I'm unfamiliar with.



    SELECT 
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName) AS total,
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
    (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_C BETWEEN 100 AND 199) AS code_c_count
    FROM table_one
    WHERE ROWNUM=1






    share|improve this question





















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I currently have 6 very similar queries that I'm trying to increase performance on by making them all subqueries in 1 query. I'm not sure what is better performance wise, keeping them 6 separate queries, 1 query with 6 subqueries (as shown below), or some other method that I'm unfamiliar with.



      SELECT 
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName) AS total,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_C BETWEEN 100 AND 199) AS code_c_count
      FROM table_one
      WHERE ROWNUM=1






      share|improve this question











      I currently have 6 very similar queries that I'm trying to increase performance on by making them all subqueries in 1 query. I'm not sure what is better performance wise, keeping them 6 separate queries, 1 query with 6 subqueries (as shown below), or some other method that I'm unfamiliar with.



      SELECT 
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName) AS total,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
      (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_C BETWEEN 100 AND 199) AS code_c_count
      FROM table_one
      WHERE ROWNUM=1








      share|improve this question










      share|improve this question




      share|improve this question









      asked Jan 26 at 19:45









      amallard

      21039




      21039




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote













          I can suggest you use common table expression (Oracle calls it "Subquery Factoring") at the very least you will be doing the filtering by date and name one time only



          WITH filter_by_date_name AS ( 
          SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
          )
          SELECT
          (SELECT COUNT(*) FROM filter_by_date_name) AS total,
          (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
          (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
          (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
          (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
          (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
          FROM filter_by_date_name
          WHERE ROWNUM=1





          share|improve this answer




























            up vote
            1
            down vote













            This is a simple task for conditional aggregation using CASEs:



            SELECT 
            COUNT(*) AS total,
            COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
            COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
            COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
            COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
            COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
            FROM table_one
            WHERE date=myDate AND name=myName


            As you're COUNTing you can return anything (besides NULL) in THEN.



            This can also be written as a SUM over 1/0:



            SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)





            share|improve this answer





















              Your Answer




              StackExchange.ifUsing("editor", function ()
              return StackExchange.using("mathjaxEditing", function ()
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              );
              );
              , "mathjax-editing");

              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: "196"
              ;
              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: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186078%2fselect-multiple-count-queries-in-single-query%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              I can suggest you use common table expression (Oracle calls it "Subquery Factoring") at the very least you will be doing the filtering by date and name one time only



              WITH filter_by_date_name AS ( 
              SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
              )
              SELECT
              (SELECT COUNT(*) FROM filter_by_date_name) AS total,
              (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
              (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
              (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
              (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
              (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
              FROM filter_by_date_name
              WHERE ROWNUM=1





              share|improve this answer

























                up vote
                1
                down vote













                I can suggest you use common table expression (Oracle calls it "Subquery Factoring") at the very least you will be doing the filtering by date and name one time only



                WITH filter_by_date_name AS ( 
                SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
                )
                SELECT
                (SELECT COUNT(*) FROM filter_by_date_name) AS total,
                (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
                (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
                (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
                (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
                (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
                FROM filter_by_date_name
                WHERE ROWNUM=1





                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  I can suggest you use common table expression (Oracle calls it "Subquery Factoring") at the very least you will be doing the filtering by date and name one time only



                  WITH filter_by_date_name AS ( 
                  SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
                  )
                  SELECT
                  (SELECT COUNT(*) FROM filter_by_date_name) AS total,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
                  FROM filter_by_date_name
                  WHERE ROWNUM=1





                  share|improve this answer













                  I can suggest you use common table expression (Oracle calls it "Subquery Factoring") at the very least you will be doing the filtering by date and name one time only



                  WITH filter_by_date_name AS ( 
                  SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
                  )
                  SELECT
                  (SELECT COUNT(*) FROM filter_by_date_name) AS total,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
                  (SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
                  FROM filter_by_date_name
                  WHERE ROWNUM=1






                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Jan 29 at 10:46









                  Sharon Ben Asher

                  2,073512




                  2,073512






















                      up vote
                      1
                      down vote













                      This is a simple task for conditional aggregation using CASEs:



                      SELECT 
                      COUNT(*) AS total,
                      COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
                      COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
                      COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
                      COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
                      COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
                      FROM table_one
                      WHERE date=myDate AND name=myName


                      As you're COUNTing you can return anything (besides NULL) in THEN.



                      This can also be written as a SUM over 1/0:



                      SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)





                      share|improve this answer

























                        up vote
                        1
                        down vote













                        This is a simple task for conditional aggregation using CASEs:



                        SELECT 
                        COUNT(*) AS total,
                        COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
                        COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
                        COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
                        COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
                        COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
                        FROM table_one
                        WHERE date=myDate AND name=myName


                        As you're COUNTing you can return anything (besides NULL) in THEN.



                        This can also be written as a SUM over 1/0:



                        SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)





                        share|improve this answer























                          up vote
                          1
                          down vote










                          up vote
                          1
                          down vote









                          This is a simple task for conditional aggregation using CASEs:



                          SELECT 
                          COUNT(*) AS total,
                          COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
                          COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
                          COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
                          COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
                          COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
                          FROM table_one
                          WHERE date=myDate AND name=myName


                          As you're COUNTing you can return anything (besides NULL) in THEN.



                          This can also be written as a SUM over 1/0:



                          SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)





                          share|improve this answer













                          This is a simple task for conditional aggregation using CASEs:



                          SELECT 
                          COUNT(*) AS total,
                          COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
                          COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
                          COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
                          COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
                          COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
                          FROM table_one
                          WHERE date=myDate AND name=myName


                          As you're COUNTing you can return anything (besides NULL) in THEN.



                          This can also be written as a SUM over 1/0:



                          SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)






                          share|improve this answer













                          share|improve this answer



                          share|improve this answer











                          answered Jan 29 at 15:48









                          dnoeth

                          1,14235




                          1,14235






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186078%2fselect-multiple-count-queries-in-single-query%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Chat program with C++ and SFML

                              Function to Return a JSON Like Objects Using VBA Collections and Arrays

                              Will my employers contract hold up in court?