简体   繁体   中英

PostgreSQL query to select data counts in table by bucket(day, month etc.) and display even if 0 count

I have a query

SELECT COUNT(*), date_trunc($1,created_at) AS bucket
        FROM chatbots.chat_message WHERE chat_id=$2 
        AND date(created_at) >= $3 and date(created_at) <= $4 
        GROUP BY bucket

data i send to sql is [bucket, chat_id, startWith, endWith]

For 'month' it returns an array with data count grouped by bucket i set:

"messagesCount": [
      {
        "count": "65323",
        "date": "2021-03"
      }
    ],

For 'day':

"messagesCount": [
      {
        "count": "55",
        "date": "2021-03-17"
      },
      {
        "count": "172",
        "date": "2021-03-19"
      },
      {
        "count": "8346",
        "date": "2021-03-22"
      },
      {
        "count": "8",
        "date": "2021-03-23"
      }
    ],

So, for example, for day it should add two more objects for period 2021.03.17 - 2021.03.23 but with 0 count

{
  "count": "0",
  "date": "2021-03-18"
},
{
  "count": "0",
  "date": "2021-03-21"
},

How can i do this? i tried to LEFT JOIN table to itself, but it does not working. Also tried COALESCE, but for sure i am doing something wrong.

I can achieve this by writing js code, but this prob will not be the best decision.

You can express the query for day as:

SELECT COUNT(cm.chat_id), gs.bucket
FROM generate_series($3, $4, interval '1 day') gs(bucket) LEFT JOIN
     chatbots.chat_message cm
     ON cm.chat_id = $2 AND
        cm.created_at >= gs.bucket AND
        cm.created_at < gs.bucket + interval '1 day'
GROUP BY bucket;

To put this into a parameterized query, change the parameter to an interval and use that for the query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM