Home > Mobile >  How to us CASE WHEN aggregation with bookshelf
How to us CASE WHEN aggregation with bookshelf

Time:02-21

I'm working with PostgreSQL and bookshelf and trying to run a simple SQL query in order to get multiple counts in a single query. This query look like:

SELECT SUM(CASE WHEN date_last_check > (now() - interval '1 MONTH') THEN 1 ELSE 0 END) as since_two_months,
       SUM(CASE WHEN date_last_check > (now() - interval '7 DAY') THEN 1 ELSE 0 END) as since_one_week,
       SUM(CASE WHEN date_last_check > (now() - interval '1 DAY') THEN 1 ELSE 0 END) as since_one_days
FROM myTable;

It seems impossible to do a CASE statement in a sum() function in bookshelf. I'm tried:

return myTable.query(function(qb:any){
  qb.sum("(CASE WHEN date_last_check > (now() - interval '1 MONTH') THEN 1 ELSE 0 END) as since_two_months")
})

And this returns the following query:

select sum("(SUM(CASE WHEN date_last_check > (now() - interval '1 MONTH') THEN 1 ELSE 0 END)") as "since_two_months" from "myTable"

This does not work because of the quotes after the sum(").

Does anyone know how to make this work without using a raw query?

CodePudding user response:

I found a poor solution, it's to use knew raw inside the bookshelf query : return myTable.query(function(qb:any){ qb.select(bookshelf.knex.raw("SUM(CASE WHEN date_last_check > (now() - interval '1 MONTH') THEN 1 ELSE 0 END) as since_one_month")); })

CodePudding user response:

Rather use modern syntax for conditional aggregates: the aggregate FILTER clause:

SELECT count(*) FILTER (WHERE date_last_check > now() - interval '1 month') AS since_two_months  -- one_month?
     , count(*) FILTER (WHERE date_last_check > now() - interval '7 days')  AS since_one_week
     , count(*) FILTER (WHERE date_last_check > now() - interval '1 day')   AS since_one_day
FROM   mytable;

See:

  • Related