简体   繁体   中英

Postgres/Sequelize - Append clause in a query conditionally

I have a Table which has some records. I have to filter those records between 2 dates or after/before a given date, or no filter at all if no dates are passed. Dates are coming by server route payload. Query is something like this:

select * from table where "id"=4 and (s2."createdAt" >= date("createdAt") and s2."createdAt" <= date("createdAt"))

Here, either first createdAt may be given, or second, or none at all in case of which the query wouldn't have and clause and will complete at "id"=4 . I am using sequelize to write the raw query and JavaScript/NodeJS for implementation. Here is the code:

 query = await sequelize.query(`select * from "Stores" s2 where "Id" = ${user.id} and (s2."createdAt" >='${param.fromDate}' and s2."createdAt <='${param.toDate}') group by date("createdAt")`);

Currently, i am writing 4 different if/else cases with 4 different queries respective to availability of date. How can i have it dynamic by defining just one query and appending dates if available?

You could do:

where 
    id = :user.id
    and (:param_from_date is null or s2."createdAt" >= :param_from_date)
    and (:param_to_date is null   or s2."createdAt" <= :param_to_date)

This can be shortened as:

where 
    id = :user_id
    and s2."createdAt" >= coalesce(:param_from_date, s2."createdAt")
    and s2."createdAt" <= coalesce(:param_to_date, s2."createdAt")

Note that these expressions use query parameters instead of mungling values in the query string. You do want to use parameterized query to protect your queries againts SQL injection and make them more efficient.

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