Classifying counts of repeat visits per user for a website

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
1












I am trying to get number of times (or sessions) a user re-visited the website.



What I'm trying to find out-



Get the total number of users, number of sessions in the last 30days. I need to a pie chart ultimately where it shows people who revisited-



  1. more than 100 times,

  2. 50-100 times,

  3. less than 50 times

The problem with the current implementation I see is -



The whole set of data(like 100million rows) are being computed every time(for each query with different condition)



SELECT COUNT(A.sess) as acount, SUM(A.sess) as asum, AVG(A.sess) as aavg
FROM
(SELECT ipaddress,
COUNT(*) AS sess
FROM analytics
WHERE trunc(datecreated) > getdate() - interval '30 days'
GROUP BY trunc(datecreated), ipaddress
HAVING COUNT(*) >= 100) AS A

UNION ALL

SELECT COUNT(B.sess) as bcount, SUM(B.sess) as bsum, AVG(B.sess) as bavg
FROM
(SELECT ipaddress,
COUNT(*) AS sess
FROM analytics
WHERE trunc(datecreated) > getdate() - interval '30 days'
GROUP BY trunc(datecreated), ipaddress
HAVING COUNT(*) < 100 AND COUNT(*) >=50 ) AS B

UNION ALL

SELECT COUNT(C.sess) as ccount, SUM(C.sess) as csum, AVG(C.sess) as cavg
FROM
(SELECT ipaddress,
COUNT(*) AS sess
FROM analytics
WHERE trunc(datecreated) > getdate() - interval '30 days'
GROUP BY trunc(datecreated), ipaddress
HAVING COUNT(*) < 50 ) AS C


How do I optimize the query?







share|improve this question



























    up vote
    1
    down vote

    favorite
    1












    I am trying to get number of times (or sessions) a user re-visited the website.



    What I'm trying to find out-



    Get the total number of users, number of sessions in the last 30days. I need to a pie chart ultimately where it shows people who revisited-



    1. more than 100 times,

    2. 50-100 times,

    3. less than 50 times

    The problem with the current implementation I see is -



    The whole set of data(like 100million rows) are being computed every time(for each query with different condition)



    SELECT COUNT(A.sess) as acount, SUM(A.sess) as asum, AVG(A.sess) as aavg
    FROM
    (SELECT ipaddress,
    COUNT(*) AS sess
    FROM analytics
    WHERE trunc(datecreated) > getdate() - interval '30 days'
    GROUP BY trunc(datecreated), ipaddress
    HAVING COUNT(*) >= 100) AS A

    UNION ALL

    SELECT COUNT(B.sess) as bcount, SUM(B.sess) as bsum, AVG(B.sess) as bavg
    FROM
    (SELECT ipaddress,
    COUNT(*) AS sess
    FROM analytics
    WHERE trunc(datecreated) > getdate() - interval '30 days'
    GROUP BY trunc(datecreated), ipaddress
    HAVING COUNT(*) < 100 AND COUNT(*) >=50 ) AS B

    UNION ALL

    SELECT COUNT(C.sess) as ccount, SUM(C.sess) as csum, AVG(C.sess) as cavg
    FROM
    (SELECT ipaddress,
    COUNT(*) AS sess
    FROM analytics
    WHERE trunc(datecreated) > getdate() - interval '30 days'
    GROUP BY trunc(datecreated), ipaddress
    HAVING COUNT(*) < 50 ) AS C


    How do I optimize the query?







    share|improve this question























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      I am trying to get number of times (or sessions) a user re-visited the website.



      What I'm trying to find out-



      Get the total number of users, number of sessions in the last 30days. I need to a pie chart ultimately where it shows people who revisited-



      1. more than 100 times,

      2. 50-100 times,

      3. less than 50 times

      The problem with the current implementation I see is -



      The whole set of data(like 100million rows) are being computed every time(for each query with different condition)



      SELECT COUNT(A.sess) as acount, SUM(A.sess) as asum, AVG(A.sess) as aavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) >= 100) AS A

      UNION ALL

      SELECT COUNT(B.sess) as bcount, SUM(B.sess) as bsum, AVG(B.sess) as bavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) < 100 AND COUNT(*) >=50 ) AS B

      UNION ALL

      SELECT COUNT(C.sess) as ccount, SUM(C.sess) as csum, AVG(C.sess) as cavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) < 50 ) AS C


      How do I optimize the query?







      share|improve this question













      I am trying to get number of times (or sessions) a user re-visited the website.



      What I'm trying to find out-



      Get the total number of users, number of sessions in the last 30days. I need to a pie chart ultimately where it shows people who revisited-



      1. more than 100 times,

      2. 50-100 times,

      3. less than 50 times

      The problem with the current implementation I see is -



      The whole set of data(like 100million rows) are being computed every time(for each query with different condition)



      SELECT COUNT(A.sess) as acount, SUM(A.sess) as asum, AVG(A.sess) as aavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) >= 100) AS A

      UNION ALL

      SELECT COUNT(B.sess) as bcount, SUM(B.sess) as bsum, AVG(B.sess) as bavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) < 100 AND COUNT(*) >=50 ) AS B

      UNION ALL

      SELECT COUNT(C.sess) as ccount, SUM(C.sess) as csum, AVG(C.sess) as cavg
      FROM
      (SELECT ipaddress,
      COUNT(*) AS sess
      FROM analytics
      WHERE trunc(datecreated) > getdate() - interval '30 days'
      GROUP BY trunc(datecreated), ipaddress
      HAVING COUNT(*) < 50 ) AS C


      How do I optimize the query?









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jan 17 at 12:51









      200_success

      123k14143401




      123k14143401









      asked Jan 17 at 11:11









      bozzmob

      1064




      1064




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          MySQL version 8 supports common table expression. If you want to differentiate between the three sub queries, use a column containing literal:



          WITH SESSIONS_THIS_MONTH AS (
          SELECT ipaddress,
          COUNT(*) AS sess
          FROM analytics
          WHERE trunc(datecreated) > getdate() - interval '30 days'
          GROUP BY trunc(datecreated), ipaddress
          )
          SELECT 'MORE THAN 100' AS CATEGORY,
          COUNT(SESSIONS_THIS_MONTH.sess) as acount,
          SUM(SESSIONS_THIS_MONTH.sess) as asum,
          AVG(SESSIONS_THIS_MONTH.sess) as aavg
          FROM SESSIONS_THIS_MONTH
          WHERE sess >= 100

          UNION ALL

          SELECT 'BETWEEN 50 AND 100' AS CATEGORY,
          COUNT(SESSIONS_THIS_MONTH.sess) as bcount,
          SUM(SESSIONS_THIS_MONTH.sess) as bsum,
          AVG(SESSIONS_THIS_MONTH.sess) as bavg
          FROM SESSIONS_THIS_MONTH
          WHERE sess < 100 AND sess >=50

          UNION ALL

          SELECT 'LESS THAN 50' AS CATEGORY,
          COUNT(SESSIONS_THIS_MONTH.sess) as ccount,
          SUM(SESSIONS_THIS_MONTH.sess) as csum,
          AVG(SESSIONS_THIS_MONTH.sess) as cavg
          FROM SESSIONS_THIS_MONTH
          WHERE sess < 50





          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%2f185296%2fclassifying-counts-of-repeat-visits-per-user-for-a-website%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote













            MySQL version 8 supports common table expression. If you want to differentiate between the three sub queries, use a column containing literal:



            WITH SESSIONS_THIS_MONTH AS (
            SELECT ipaddress,
            COUNT(*) AS sess
            FROM analytics
            WHERE trunc(datecreated) > getdate() - interval '30 days'
            GROUP BY trunc(datecreated), ipaddress
            )
            SELECT 'MORE THAN 100' AS CATEGORY,
            COUNT(SESSIONS_THIS_MONTH.sess) as acount,
            SUM(SESSIONS_THIS_MONTH.sess) as asum,
            AVG(SESSIONS_THIS_MONTH.sess) as aavg
            FROM SESSIONS_THIS_MONTH
            WHERE sess >= 100

            UNION ALL

            SELECT 'BETWEEN 50 AND 100' AS CATEGORY,
            COUNT(SESSIONS_THIS_MONTH.sess) as bcount,
            SUM(SESSIONS_THIS_MONTH.sess) as bsum,
            AVG(SESSIONS_THIS_MONTH.sess) as bavg
            FROM SESSIONS_THIS_MONTH
            WHERE sess < 100 AND sess >=50

            UNION ALL

            SELECT 'LESS THAN 50' AS CATEGORY,
            COUNT(SESSIONS_THIS_MONTH.sess) as ccount,
            SUM(SESSIONS_THIS_MONTH.sess) as csum,
            AVG(SESSIONS_THIS_MONTH.sess) as cavg
            FROM SESSIONS_THIS_MONTH
            WHERE sess < 50





            share|improve this answer



























              up vote
              1
              down vote













              MySQL version 8 supports common table expression. If you want to differentiate between the three sub queries, use a column containing literal:



              WITH SESSIONS_THIS_MONTH AS (
              SELECT ipaddress,
              COUNT(*) AS sess
              FROM analytics
              WHERE trunc(datecreated) > getdate() - interval '30 days'
              GROUP BY trunc(datecreated), ipaddress
              )
              SELECT 'MORE THAN 100' AS CATEGORY,
              COUNT(SESSIONS_THIS_MONTH.sess) as acount,
              SUM(SESSIONS_THIS_MONTH.sess) as asum,
              AVG(SESSIONS_THIS_MONTH.sess) as aavg
              FROM SESSIONS_THIS_MONTH
              WHERE sess >= 100

              UNION ALL

              SELECT 'BETWEEN 50 AND 100' AS CATEGORY,
              COUNT(SESSIONS_THIS_MONTH.sess) as bcount,
              SUM(SESSIONS_THIS_MONTH.sess) as bsum,
              AVG(SESSIONS_THIS_MONTH.sess) as bavg
              FROM SESSIONS_THIS_MONTH
              WHERE sess < 100 AND sess >=50

              UNION ALL

              SELECT 'LESS THAN 50' AS CATEGORY,
              COUNT(SESSIONS_THIS_MONTH.sess) as ccount,
              SUM(SESSIONS_THIS_MONTH.sess) as csum,
              AVG(SESSIONS_THIS_MONTH.sess) as cavg
              FROM SESSIONS_THIS_MONTH
              WHERE sess < 50





              share|improve this answer

























                up vote
                1
                down vote










                up vote
                1
                down vote









                MySQL version 8 supports common table expression. If you want to differentiate between the three sub queries, use a column containing literal:



                WITH SESSIONS_THIS_MONTH AS (
                SELECT ipaddress,
                COUNT(*) AS sess
                FROM analytics
                WHERE trunc(datecreated) > getdate() - interval '30 days'
                GROUP BY trunc(datecreated), ipaddress
                )
                SELECT 'MORE THAN 100' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as acount,
                SUM(SESSIONS_THIS_MONTH.sess) as asum,
                AVG(SESSIONS_THIS_MONTH.sess) as aavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess >= 100

                UNION ALL

                SELECT 'BETWEEN 50 AND 100' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as bcount,
                SUM(SESSIONS_THIS_MONTH.sess) as bsum,
                AVG(SESSIONS_THIS_MONTH.sess) as bavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess < 100 AND sess >=50

                UNION ALL

                SELECT 'LESS THAN 50' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as ccount,
                SUM(SESSIONS_THIS_MONTH.sess) as csum,
                AVG(SESSIONS_THIS_MONTH.sess) as cavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess < 50





                share|improve this answer















                MySQL version 8 supports common table expression. If you want to differentiate between the three sub queries, use a column containing literal:



                WITH SESSIONS_THIS_MONTH AS (
                SELECT ipaddress,
                COUNT(*) AS sess
                FROM analytics
                WHERE trunc(datecreated) > getdate() - interval '30 days'
                GROUP BY trunc(datecreated), ipaddress
                )
                SELECT 'MORE THAN 100' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as acount,
                SUM(SESSIONS_THIS_MONTH.sess) as asum,
                AVG(SESSIONS_THIS_MONTH.sess) as aavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess >= 100

                UNION ALL

                SELECT 'BETWEEN 50 AND 100' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as bcount,
                SUM(SESSIONS_THIS_MONTH.sess) as bsum,
                AVG(SESSIONS_THIS_MONTH.sess) as bavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess < 100 AND sess >=50

                UNION ALL

                SELECT 'LESS THAN 50' AS CATEGORY,
                COUNT(SESSIONS_THIS_MONTH.sess) as ccount,
                SUM(SESSIONS_THIS_MONTH.sess) as csum,
                AVG(SESSIONS_THIS_MONTH.sess) as cavg
                FROM SESSIONS_THIS_MONTH
                WHERE sess < 50






                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jan 17 at 13:38


























                answered Jan 17 at 13:32









                Sharon Ben Asher

                2,073512




                2,073512






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f185296%2fclassifying-counts-of-repeat-visits-per-user-for-a-website%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?