Return 0 for all missing combinations in the joined table











up vote
2
down vote

favorite












I have 2 tables, timeseries and orders



timeseries



+------------+
| datetime |
+------------+
| 2018-11-01 |
| 2018-11-02 |
| 2018-11-03 |
+------------+


orders



+------------+-------------+----------+
| datetime | customer_id | order_id |
+------------+-------------+----------+
| 2018-11-01 | 1 | 1 |
| 2018-11-02 | 1 | 2 |
| 2018-11-03 | 2 | 3 |
+------------+-------------+----------+


I would like to get number of orders for each customer in each day.



Expected results:



+------------+-------------+--------------+
| datetime | customer_id | number_order |
+------------+-------------+--------------+
| 2018-11-01 | 1 | 1 |
| 2018-11-02 | 1 | 1 |
| 2018-11-03 | 1 | 0 |
| 2018-11-01 | 2 | 0 |
| 2018-11-02 | 2 | 0 |
| 2018-11-03 | 2 | 1 |
+------------+-------------+--------------+


I tried LEFT JOIN, but it doesn't return all time series for all customer



SELECT datetime, customer_id, COUNT(order_id) as number_order 
FROM timeseries
LEFT JOIN orders
ON timeseries.datetime = orders.datetime
GROUP BY datetime, customer_id
ORDER BY datetime, customer_id

>> Result

+------------+-------------+--------------+
| datetime | customer_id | number_order |
+------------+-------------+--------------+
| 2018-11-01 | 1 | 1 |
| 2018-11-02 | 1 | 1 |
| 2018-11-03 | 2 | 1 |
+------------+-------------+--------------+


I understand left join only ensures returning all rows in table timeseries, but what I need is all rows in table timeseries with each customer_id.



Thank for your help!










share|improve this question




























    up vote
    2
    down vote

    favorite












    I have 2 tables, timeseries and orders



    timeseries



    +------------+
    | datetime |
    +------------+
    | 2018-11-01 |
    | 2018-11-02 |
    | 2018-11-03 |
    +------------+


    orders



    +------------+-------------+----------+
    | datetime | customer_id | order_id |
    +------------+-------------+----------+
    | 2018-11-01 | 1 | 1 |
    | 2018-11-02 | 1 | 2 |
    | 2018-11-03 | 2 | 3 |
    +------------+-------------+----------+


    I would like to get number of orders for each customer in each day.



    Expected results:



    +------------+-------------+--------------+
    | datetime | customer_id | number_order |
    +------------+-------------+--------------+
    | 2018-11-01 | 1 | 1 |
    | 2018-11-02 | 1 | 1 |
    | 2018-11-03 | 1 | 0 |
    | 2018-11-01 | 2 | 0 |
    | 2018-11-02 | 2 | 0 |
    | 2018-11-03 | 2 | 1 |
    +------------+-------------+--------------+


    I tried LEFT JOIN, but it doesn't return all time series for all customer



    SELECT datetime, customer_id, COUNT(order_id) as number_order 
    FROM timeseries
    LEFT JOIN orders
    ON timeseries.datetime = orders.datetime
    GROUP BY datetime, customer_id
    ORDER BY datetime, customer_id

    >> Result

    +------------+-------------+--------------+
    | datetime | customer_id | number_order |
    +------------+-------------+--------------+
    | 2018-11-01 | 1 | 1 |
    | 2018-11-02 | 1 | 1 |
    | 2018-11-03 | 2 | 1 |
    +------------+-------------+--------------+


    I understand left join only ensures returning all rows in table timeseries, but what I need is all rows in table timeseries with each customer_id.



    Thank for your help!










    share|improve this question


























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I have 2 tables, timeseries and orders



      timeseries



      +------------+
      | datetime |
      +------------+
      | 2018-11-01 |
      | 2018-11-02 |
      | 2018-11-03 |
      +------------+


      orders



      +------------+-------------+----------+
      | datetime | customer_id | order_id |
      +------------+-------------+----------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 2 |
      | 2018-11-03 | 2 | 3 |
      +------------+-------------+----------+


      I would like to get number of orders for each customer in each day.



      Expected results:



      +------------+-------------+--------------+
      | datetime | customer_id | number_order |
      +------------+-------------+--------------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 1 |
      | 2018-11-03 | 1 | 0 |
      | 2018-11-01 | 2 | 0 |
      | 2018-11-02 | 2 | 0 |
      | 2018-11-03 | 2 | 1 |
      +------------+-------------+--------------+


      I tried LEFT JOIN, but it doesn't return all time series for all customer



      SELECT datetime, customer_id, COUNT(order_id) as number_order 
      FROM timeseries
      LEFT JOIN orders
      ON timeseries.datetime = orders.datetime
      GROUP BY datetime, customer_id
      ORDER BY datetime, customer_id

      >> Result

      +------------+-------------+--------------+
      | datetime | customer_id | number_order |
      +------------+-------------+--------------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 1 |
      | 2018-11-03 | 2 | 1 |
      +------------+-------------+--------------+


      I understand left join only ensures returning all rows in table timeseries, but what I need is all rows in table timeseries with each customer_id.



      Thank for your help!










      share|improve this question















      I have 2 tables, timeseries and orders



      timeseries



      +------------+
      | datetime |
      +------------+
      | 2018-11-01 |
      | 2018-11-02 |
      | 2018-11-03 |
      +------------+


      orders



      +------------+-------------+----------+
      | datetime | customer_id | order_id |
      +------------+-------------+----------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 2 |
      | 2018-11-03 | 2 | 3 |
      +------------+-------------+----------+


      I would like to get number of orders for each customer in each day.



      Expected results:



      +------------+-------------+--------------+
      | datetime | customer_id | number_order |
      +------------+-------------+--------------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 1 |
      | 2018-11-03 | 1 | 0 |
      | 2018-11-01 | 2 | 0 |
      | 2018-11-02 | 2 | 0 |
      | 2018-11-03 | 2 | 1 |
      +------------+-------------+--------------+


      I tried LEFT JOIN, but it doesn't return all time series for all customer



      SELECT datetime, customer_id, COUNT(order_id) as number_order 
      FROM timeseries
      LEFT JOIN orders
      ON timeseries.datetime = orders.datetime
      GROUP BY datetime, customer_id
      ORDER BY datetime, customer_id

      >> Result

      +------------+-------------+--------------+
      | datetime | customer_id | number_order |
      +------------+-------------+--------------+
      | 2018-11-01 | 1 | 1 |
      | 2018-11-02 | 1 | 1 |
      | 2018-11-03 | 2 | 1 |
      +------------+-------------+--------------+


      I understand left join only ensures returning all rows in table timeseries, but what I need is all rows in table timeseries with each customer_id.



      Thank for your help!







      sql postgresql group-by left-join cross-join






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 10:19









      Salman A

      172k65330415




      172k65330415










      asked Nov 19 at 6:23









      ittus

      5,2771723




      5,2771723
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          You need to cross join all dates and all customers to get all possibile combinations of date and customer ids. Then left join with orders:



          SELECT timeseries.datetime, customers.customer_id, COUNT(orders.order_id) as number_order
          FROM timeseries
          CROSS JOIN (SELECT DISTINCT customer_id FROM orders) AS customers
          LEFT JOIN orders ON orders.datetime = timeseries.datetime AND orders.customer_id = customers.customer_id
          GROUP BY timeseries.datetime, customers.customer_id
          ORDER BY timeseries.datetime, customers.customer_id





          share|improve this answer




























            up vote
            0
            down vote













            use union all then left join



            select t1.datetime,customer_id,COUNT(order_id) as number_order from 

            (select datetime from timeseries
            union all
            select datetime from orders
            ) t1 left join
            orders on t1.datetime=orders.datetime
            group by t1.datetime,customer_id





            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%2f53369318%2freturn-0-for-all-missing-combinations-in-the-joined-table%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
              4
              down vote



              accepted










              You need to cross join all dates and all customers to get all possibile combinations of date and customer ids. Then left join with orders:



              SELECT timeseries.datetime, customers.customer_id, COUNT(orders.order_id) as number_order
              FROM timeseries
              CROSS JOIN (SELECT DISTINCT customer_id FROM orders) AS customers
              LEFT JOIN orders ON orders.datetime = timeseries.datetime AND orders.customer_id = customers.customer_id
              GROUP BY timeseries.datetime, customers.customer_id
              ORDER BY timeseries.datetime, customers.customer_id





              share|improve this answer

























                up vote
                4
                down vote



                accepted










                You need to cross join all dates and all customers to get all possibile combinations of date and customer ids. Then left join with orders:



                SELECT timeseries.datetime, customers.customer_id, COUNT(orders.order_id) as number_order
                FROM timeseries
                CROSS JOIN (SELECT DISTINCT customer_id FROM orders) AS customers
                LEFT JOIN orders ON orders.datetime = timeseries.datetime AND orders.customer_id = customers.customer_id
                GROUP BY timeseries.datetime, customers.customer_id
                ORDER BY timeseries.datetime, customers.customer_id





                share|improve this answer























                  up vote
                  4
                  down vote



                  accepted







                  up vote
                  4
                  down vote



                  accepted






                  You need to cross join all dates and all customers to get all possibile combinations of date and customer ids. Then left join with orders:



                  SELECT timeseries.datetime, customers.customer_id, COUNT(orders.order_id) as number_order
                  FROM timeseries
                  CROSS JOIN (SELECT DISTINCT customer_id FROM orders) AS customers
                  LEFT JOIN orders ON orders.datetime = timeseries.datetime AND orders.customer_id = customers.customer_id
                  GROUP BY timeseries.datetime, customers.customer_id
                  ORDER BY timeseries.datetime, customers.customer_id





                  share|improve this answer












                  You need to cross join all dates and all customers to get all possibile combinations of date and customer ids. Then left join with orders:



                  SELECT timeseries.datetime, customers.customer_id, COUNT(orders.order_id) as number_order
                  FROM timeseries
                  CROSS JOIN (SELECT DISTINCT customer_id FROM orders) AS customers
                  LEFT JOIN orders ON orders.datetime = timeseries.datetime AND orders.customer_id = customers.customer_id
                  GROUP BY timeseries.datetime, customers.customer_id
                  ORDER BY timeseries.datetime, customers.customer_id






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 19 at 6:29









                  Salman A

                  172k65330415




                  172k65330415
























                      up vote
                      0
                      down vote













                      use union all then left join



                      select t1.datetime,customer_id,COUNT(order_id) as number_order from 

                      (select datetime from timeseries
                      union all
                      select datetime from orders
                      ) t1 left join
                      orders on t1.datetime=orders.datetime
                      group by t1.datetime,customer_id





                      share|improve this answer

























                        up vote
                        0
                        down vote













                        use union all then left join



                        select t1.datetime,customer_id,COUNT(order_id) as number_order from 

                        (select datetime from timeseries
                        union all
                        select datetime from orders
                        ) t1 left join
                        orders on t1.datetime=orders.datetime
                        group by t1.datetime,customer_id





                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          use union all then left join



                          select t1.datetime,customer_id,COUNT(order_id) as number_order from 

                          (select datetime from timeseries
                          union all
                          select datetime from orders
                          ) t1 left join
                          orders on t1.datetime=orders.datetime
                          group by t1.datetime,customer_id





                          share|improve this answer












                          use union all then left join



                          select t1.datetime,customer_id,COUNT(order_id) as number_order from 

                          (select datetime from timeseries
                          union all
                          select datetime from orders
                          ) t1 left join
                          orders on t1.datetime=orders.datetime
                          group by t1.datetime,customer_id






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 19 at 6:27









                          Zaynul Abadin Tuhin

                          10.6k2731




                          10.6k2731






























                               

                              draft saved


                              draft discarded



















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53369318%2freturn-0-for-all-missing-combinations-in-the-joined-table%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