Group By - select by a criteria that is met every month












2















The below query returns all USERS that have SUM(AMOUNT) > 10 in a given month. It includes Users in a month even if they don't meet the criteria in other months.



But I'd like to transform this query to return all USERS who must meet the criteria SUM(AMOUNT) > 10 every single month (i.e., from the first month in the table to the last one) across the entire data.



Put another way, exclude users who don't meet SUM(AMOUNT) > 10 every single month.



select USERS, to_char(transaction_date, 'YYYY-MM') as month
from Table
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10;









share|improve this question

























  • What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

    – Thorsten Kettner
    Nov 24 '18 at 16:31













  • It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

    – Himanshu Ahuja
    Nov 24 '18 at 16:39













  • @Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

    – ZJAY
    Nov 24 '18 at 17:37











  • What if there's a missing month for a user?

    – dnoeth
    Nov 24 '18 at 19:06











  • @dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

    – ZJAY
    Nov 24 '18 at 19:12
















2















The below query returns all USERS that have SUM(AMOUNT) > 10 in a given month. It includes Users in a month even if they don't meet the criteria in other months.



But I'd like to transform this query to return all USERS who must meet the criteria SUM(AMOUNT) > 10 every single month (i.e., from the first month in the table to the last one) across the entire data.



Put another way, exclude users who don't meet SUM(AMOUNT) > 10 every single month.



select USERS, to_char(transaction_date, 'YYYY-MM') as month
from Table
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10;









share|improve this question

























  • What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

    – Thorsten Kettner
    Nov 24 '18 at 16:31













  • It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

    – Himanshu Ahuja
    Nov 24 '18 at 16:39













  • @Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

    – ZJAY
    Nov 24 '18 at 17:37











  • What if there's a missing month for a user?

    – dnoeth
    Nov 24 '18 at 19:06











  • @dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

    – ZJAY
    Nov 24 '18 at 19:12














2












2








2








The below query returns all USERS that have SUM(AMOUNT) > 10 in a given month. It includes Users in a month even if they don't meet the criteria in other months.



But I'd like to transform this query to return all USERS who must meet the criteria SUM(AMOUNT) > 10 every single month (i.e., from the first month in the table to the last one) across the entire data.



Put another way, exclude users who don't meet SUM(AMOUNT) > 10 every single month.



select USERS, to_char(transaction_date, 'YYYY-MM') as month
from Table
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10;









share|improve this question
















The below query returns all USERS that have SUM(AMOUNT) > 10 in a given month. It includes Users in a month even if they don't meet the criteria in other months.



But I'd like to transform this query to return all USERS who must meet the criteria SUM(AMOUNT) > 10 every single month (i.e., from the first month in the table to the last one) across the entire data.



Put another way, exclude users who don't meet SUM(AMOUNT) > 10 every single month.



select USERS, to_char(transaction_date, 'YYYY-MM') as month
from Table
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10;






sql postgresql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 17:38







ZJAY

















asked Nov 24 '18 at 16:11









ZJAYZJAY

4202924




4202924













  • What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

    – Thorsten Kettner
    Nov 24 '18 at 16:31













  • It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

    – Himanshu Ahuja
    Nov 24 '18 at 16:39













  • @Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

    – ZJAY
    Nov 24 '18 at 17:37











  • What if there's a missing month for a user?

    – dnoeth
    Nov 24 '18 at 19:06











  • @dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

    – ZJAY
    Nov 24 '18 at 19:12



















  • What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

    – Thorsten Kettner
    Nov 24 '18 at 16:31













  • It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

    – Himanshu Ahuja
    Nov 24 '18 at 16:39













  • @Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

    – ZJAY
    Nov 24 '18 at 17:37











  • What if there's a missing month for a user?

    – dnoeth
    Nov 24 '18 at 19:06











  • @dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

    – ZJAY
    Nov 24 '18 at 19:12

















What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

– Thorsten Kettner
Nov 24 '18 at 16:31







What does "every single month" mean? Every month the user has an entry? Every month some user has an entry? Every month from the first month in the table to the last one? Every month in a certain time span, e.g. Jan 2018 to Oct 2018?

– Thorsten Kettner
Nov 24 '18 at 16:31















It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

– Himanshu Ahuja
Nov 24 '18 at 16:39







It is correct with respect to each month as you specified group by users,month meaning every single month group but the fact you have month with year in it doesnt mean for other years it will be same so if you can change your month format to Just 'MM'

– Himanshu Ahuja
Nov 24 '18 at 16:39















@Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

– ZJAY
Nov 24 '18 at 17:37





@Thorsten Kettner I only want to return users who have SUM(AMOUNT) > 10 from the first month in the table to the last one i.e., all months.

– ZJAY
Nov 24 '18 at 17:37













What if there's a missing month for a user?

– dnoeth
Nov 24 '18 at 19:06





What if there's a missing month for a user?

– dnoeth
Nov 24 '18 at 19:06













@dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

– ZJAY
Nov 24 '18 at 19:12





@dnoeth then they should be excluded - I'm essentially trying to build a database of consistent users

– ZJAY
Nov 24 '18 at 19:12












4 Answers
4






active

oldest

votes


















0














One approach uses a generated calendar table representing all months in your data set. We can left join this calendar table to your current query, and then aggregate over all months by user:



WITH months AS (
SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
FROM yourTable
),
cte AS (
SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
FROM yourTable
GROUP BY USERS, month
HAVING SUM(AMOUNT) > 10
)

SELECT
t.USERS
FROM months m
LEFT JOIN cte t
ON m.month = t.month
GROUP BY
t.USERS
HAVING
COUNT(t.USERS) = (SELECT COUNT(*) FROM months);


The HAVING clause above asserts that the number of months to which a user matches is in fact the total number of months. This would imply that the user meets the sum criteria for every month.






share|improve this answer































    0














    Perhaps you could use a correlated subquery, such as:



    select t.*
    from (select distinct table.users from table) t
    where not exists
    (
    select to_char(u.transaction_date, 'YYYY-MM') as month
    from table u
    where u.users = t.users
    group by month
    having sum(u.amount) <= 10
    )





    share|improve this answer































      0














      One option would be using sign(amount-10) vs. sign(amount) logic as



      SELECT q.users
      FROM
      (
      with tab(users, transaction_date,amount) as
      (
      select 1,date'2018-11-24',8 union all
      select 1,date'2018-11-24',18 union all
      select 2,date'2018-10-24',13 union all
      select 3,date'2018-11-24',18 union all
      select 3,date'2018-10-24',28 union all
      select 3,date'2018-09-24', 3 union all
      select 4,date'2018-10-24',28
      )
      SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
      sum(sign(amount-10)) as cnt1,
      sum(sign(amount)) as cnt2
      FROM tab t
      GROUP BY users, month
      ) q
      GROUP BY q.users
      HAVING sum(q.cnt1) = sum(q.cnt2)
      GROUP BY q.users

      users
      -----
      2
      4


      Rextester Demo






      share|improve this answer

































        0














        You need to compare the number of months > 10 to the number of months between the min and the max date:



        SELECT users, Count(flag) AS months, Min(mth), Max(mth)
        FROM
        (
        SELECT users, date_trunc('month',transaction_date) AS mth,
        CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
        FROM tab t
        GROUP BY users, mth
        ) AS dt
        GROUP BY users
        HAVING -- adding the number of months > 10 to the min date and compare to max
        Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)


        If missing months don't count it would be a simple count(flag) = count(*)






        share|improve this answer
























        • this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

          – ZJAY
          Nov 25 '18 at 13:42











        • Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

          – dnoeth
          Nov 25 '18 at 19:05











        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%2f53460003%2fgroup-by-select-by-a-criteria-that-is-met-every-month%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        0














        One approach uses a generated calendar table representing all months in your data set. We can left join this calendar table to your current query, and then aggregate over all months by user:



        WITH months AS (
        SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
        FROM yourTable
        ),
        cte AS (
        SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
        FROM yourTable
        GROUP BY USERS, month
        HAVING SUM(AMOUNT) > 10
        )

        SELECT
        t.USERS
        FROM months m
        LEFT JOIN cte t
        ON m.month = t.month
        GROUP BY
        t.USERS
        HAVING
        COUNT(t.USERS) = (SELECT COUNT(*) FROM months);


        The HAVING clause above asserts that the number of months to which a user matches is in fact the total number of months. This would imply that the user meets the sum criteria for every month.






        share|improve this answer




























          0














          One approach uses a generated calendar table representing all months in your data set. We can left join this calendar table to your current query, and then aggregate over all months by user:



          WITH months AS (
          SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
          FROM yourTable
          ),
          cte AS (
          SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
          FROM yourTable
          GROUP BY USERS, month
          HAVING SUM(AMOUNT) > 10
          )

          SELECT
          t.USERS
          FROM months m
          LEFT JOIN cte t
          ON m.month = t.month
          GROUP BY
          t.USERS
          HAVING
          COUNT(t.USERS) = (SELECT COUNT(*) FROM months);


          The HAVING clause above asserts that the number of months to which a user matches is in fact the total number of months. This would imply that the user meets the sum criteria for every month.






          share|improve this answer


























            0












            0








            0







            One approach uses a generated calendar table representing all months in your data set. We can left join this calendar table to your current query, and then aggregate over all months by user:



            WITH months AS (
            SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
            FROM yourTable
            ),
            cte AS (
            SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
            FROM yourTable
            GROUP BY USERS, month
            HAVING SUM(AMOUNT) > 10
            )

            SELECT
            t.USERS
            FROM months m
            LEFT JOIN cte t
            ON m.month = t.month
            GROUP BY
            t.USERS
            HAVING
            COUNT(t.USERS) = (SELECT COUNT(*) FROM months);


            The HAVING clause above asserts that the number of months to which a user matches is in fact the total number of months. This would imply that the user meets the sum criteria for every month.






            share|improve this answer













            One approach uses a generated calendar table representing all months in your data set. We can left join this calendar table to your current query, and then aggregate over all months by user:



            WITH months AS (
            SELECT DISTINCT TO_CHAR(transaction_date, 'YYYY-MM') AS month
            FROM yourTable
            ),
            cte AS (
            SELECT USERS, TO_CHAR(transaction_date, 'YYYY-MM') AS month
            FROM yourTable
            GROUP BY USERS, month
            HAVING SUM(AMOUNT) > 10
            )

            SELECT
            t.USERS
            FROM months m
            LEFT JOIN cte t
            ON m.month = t.month
            GROUP BY
            t.USERS
            HAVING
            COUNT(t.USERS) = (SELECT COUNT(*) FROM months);


            The HAVING clause above asserts that the number of months to which a user matches is in fact the total number of months. This would imply that the user meets the sum criteria for every month.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 24 '18 at 16:20









            Tim BiegeleisenTim Biegeleisen

            229k1395147




            229k1395147

























                0














                Perhaps you could use a correlated subquery, such as:



                select t.*
                from (select distinct table.users from table) t
                where not exists
                (
                select to_char(u.transaction_date, 'YYYY-MM') as month
                from table u
                where u.users = t.users
                group by month
                having sum(u.amount) <= 10
                )





                share|improve this answer




























                  0














                  Perhaps you could use a correlated subquery, such as:



                  select t.*
                  from (select distinct table.users from table) t
                  where not exists
                  (
                  select to_char(u.transaction_date, 'YYYY-MM') as month
                  from table u
                  where u.users = t.users
                  group by month
                  having sum(u.amount) <= 10
                  )





                  share|improve this answer


























                    0












                    0








                    0







                    Perhaps you could use a correlated subquery, such as:



                    select t.*
                    from (select distinct table.users from table) t
                    where not exists
                    (
                    select to_char(u.transaction_date, 'YYYY-MM') as month
                    from table u
                    where u.users = t.users
                    group by month
                    having sum(u.amount) <= 10
                    )





                    share|improve this answer













                    Perhaps you could use a correlated subquery, such as:



                    select t.*
                    from (select distinct table.users from table) t
                    where not exists
                    (
                    select to_char(u.transaction_date, 'YYYY-MM') as month
                    from table u
                    where u.users = t.users
                    group by month
                    having sum(u.amount) <= 10
                    )






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 24 '18 at 16:27









                    Lee MacLee Mac

                    4,78531541




                    4,78531541























                        0














                        One option would be using sign(amount-10) vs. sign(amount) logic as



                        SELECT q.users
                        FROM
                        (
                        with tab(users, transaction_date,amount) as
                        (
                        select 1,date'2018-11-24',8 union all
                        select 1,date'2018-11-24',18 union all
                        select 2,date'2018-10-24',13 union all
                        select 3,date'2018-11-24',18 union all
                        select 3,date'2018-10-24',28 union all
                        select 3,date'2018-09-24', 3 union all
                        select 4,date'2018-10-24',28
                        )
                        SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
                        sum(sign(amount-10)) as cnt1,
                        sum(sign(amount)) as cnt2
                        FROM tab t
                        GROUP BY users, month
                        ) q
                        GROUP BY q.users
                        HAVING sum(q.cnt1) = sum(q.cnt2)
                        GROUP BY q.users

                        users
                        -----
                        2
                        4


                        Rextester Demo






                        share|improve this answer






























                          0














                          One option would be using sign(amount-10) vs. sign(amount) logic as



                          SELECT q.users
                          FROM
                          (
                          with tab(users, transaction_date,amount) as
                          (
                          select 1,date'2018-11-24',8 union all
                          select 1,date'2018-11-24',18 union all
                          select 2,date'2018-10-24',13 union all
                          select 3,date'2018-11-24',18 union all
                          select 3,date'2018-10-24',28 union all
                          select 3,date'2018-09-24', 3 union all
                          select 4,date'2018-10-24',28
                          )
                          SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
                          sum(sign(amount-10)) as cnt1,
                          sum(sign(amount)) as cnt2
                          FROM tab t
                          GROUP BY users, month
                          ) q
                          GROUP BY q.users
                          HAVING sum(q.cnt1) = sum(q.cnt2)
                          GROUP BY q.users

                          users
                          -----
                          2
                          4


                          Rextester Demo






                          share|improve this answer




























                            0












                            0








                            0







                            One option would be using sign(amount-10) vs. sign(amount) logic as



                            SELECT q.users
                            FROM
                            (
                            with tab(users, transaction_date,amount) as
                            (
                            select 1,date'2018-11-24',8 union all
                            select 1,date'2018-11-24',18 union all
                            select 2,date'2018-10-24',13 union all
                            select 3,date'2018-11-24',18 union all
                            select 3,date'2018-10-24',28 union all
                            select 3,date'2018-09-24', 3 union all
                            select 4,date'2018-10-24',28
                            )
                            SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
                            sum(sign(amount-10)) as cnt1,
                            sum(sign(amount)) as cnt2
                            FROM tab t
                            GROUP BY users, month
                            ) q
                            GROUP BY q.users
                            HAVING sum(q.cnt1) = sum(q.cnt2)
                            GROUP BY q.users

                            users
                            -----
                            2
                            4


                            Rextester Demo






                            share|improve this answer















                            One option would be using sign(amount-10) vs. sign(amount) logic as



                            SELECT q.users
                            FROM
                            (
                            with tab(users, transaction_date,amount) as
                            (
                            select 1,date'2018-11-24',8 union all
                            select 1,date'2018-11-24',18 union all
                            select 2,date'2018-10-24',13 union all
                            select 3,date'2018-11-24',18 union all
                            select 3,date'2018-10-24',28 union all
                            select 3,date'2018-09-24', 3 union all
                            select 4,date'2018-10-24',28
                            )
                            SELECT users, to_char(transaction_date, 'YYYY-MM') as month,
                            sum(sign(amount-10)) as cnt1,
                            sum(sign(amount)) as cnt2
                            FROM tab t
                            GROUP BY users, month
                            ) q
                            GROUP BY q.users
                            HAVING sum(q.cnt1) = sum(q.cnt2)
                            GROUP BY q.users

                            users
                            -----
                            2
                            4


                            Rextester Demo







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 24 '18 at 18:02

























                            answered Nov 24 '18 at 16:26









                            Barbaros ÖzhanBarbaros Özhan

                            13.8k71633




                            13.8k71633























                                0














                                You need to compare the number of months > 10 to the number of months between the min and the max date:



                                SELECT users, Count(flag) AS months, Min(mth), Max(mth)
                                FROM
                                (
                                SELECT users, date_trunc('month',transaction_date) AS mth,
                                CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
                                FROM tab t
                                GROUP BY users, mth
                                ) AS dt
                                GROUP BY users
                                HAVING -- adding the number of months > 10 to the min date and compare to max
                                Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)


                                If missing months don't count it would be a simple count(flag) = count(*)






                                share|improve this answer
























                                • this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                  – ZJAY
                                  Nov 25 '18 at 13:42











                                • Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                  – dnoeth
                                  Nov 25 '18 at 19:05
















                                0














                                You need to compare the number of months > 10 to the number of months between the min and the max date:



                                SELECT users, Count(flag) AS months, Min(mth), Max(mth)
                                FROM
                                (
                                SELECT users, date_trunc('month',transaction_date) AS mth,
                                CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
                                FROM tab t
                                GROUP BY users, mth
                                ) AS dt
                                GROUP BY users
                                HAVING -- adding the number of months > 10 to the min date and compare to max
                                Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)


                                If missing months don't count it would be a simple count(flag) = count(*)






                                share|improve this answer
























                                • this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                  – ZJAY
                                  Nov 25 '18 at 13:42











                                • Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                  – dnoeth
                                  Nov 25 '18 at 19:05














                                0












                                0








                                0







                                You need to compare the number of months > 10 to the number of months between the min and the max date:



                                SELECT users, Count(flag) AS months, Min(mth), Max(mth)
                                FROM
                                (
                                SELECT users, date_trunc('month',transaction_date) AS mth,
                                CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
                                FROM tab t
                                GROUP BY users, mth
                                ) AS dt
                                GROUP BY users
                                HAVING -- adding the number of months > 10 to the min date and compare to max
                                Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)


                                If missing months don't count it would be a simple count(flag) = count(*)






                                share|improve this answer













                                You need to compare the number of months > 10 to the number of months between the min and the max date:



                                SELECT users, Count(flag) AS months, Min(mth), Max(mth)
                                FROM
                                (
                                SELECT users, date_trunc('month',transaction_date) AS mth,
                                CASE WHEN Sum(amount) > 10 THEN 1 end AS flag
                                FROM tab t
                                GROUP BY users, mth
                                ) AS dt
                                GROUP BY users
                                HAVING -- adding the number of months > 10 to the min date and compare to max
                                Min(mth) + (INTERVAL '1' MONTH * (Count(flag)-1)) = Max(mth)


                                If missing months don't count it would be a simple count(flag) = count(*)







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Nov 24 '18 at 19:53









                                dnoethdnoeth

                                45.7k31839




                                45.7k31839













                                • this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                  – ZJAY
                                  Nov 25 '18 at 13:42











                                • Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                  – dnoeth
                                  Nov 25 '18 at 19:05



















                                • this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                  – ZJAY
                                  Nov 25 '18 at 13:42











                                • Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                  – dnoeth
                                  Nov 25 '18 at 19:05

















                                this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                – ZJAY
                                Nov 25 '18 at 13:42





                                this returns dates for the min, max values (i.e., 2015-04-01 for min), not the number/count of months - is this intended? It's not returning the correct value as is.

                                – ZJAY
                                Nov 25 '18 at 13:42













                                Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                – dnoeth
                                Nov 25 '18 at 19:05





                                Well, Count(flag) AS months calculates the number of months. This query returns those users who had amounts > 10 from the min to the max month and no gaps. If this is not what you want you should explain why and setup a fiddle.

                                – dnoeth
                                Nov 25 '18 at 19:05


















                                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%2f53460003%2fgroup-by-select-by-a-criteria-that-is-met-every-month%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

                                Costa Masnaga

                                Fotorealismo

                                Sidney Franklin