convert sql query to sequelize query - javascript

how to convert this to sequelize query . I've tried using between but it does not have the same result. I dont think between is the solution , how about lte and gte ? Thank you
using between
where: {
createdAt: {
[Op.between]: ["2018-07-08T14:06:48.000Z", "2019-10-08T22:33:54.000Z"]
}
}
convert this sql to sequelize query
SELECT * FROM testtable WHERE createdAt >= '2020-06-15 00:00:00' AND createdAt <= '2020-06-18 00:00:00'

You can include the same property more than once within the where and this would work like AND in your SQL query:
where: {
createdAt: { [Op.gte]: '2020-06-15' },
createdAt: { [Op.lte]: '2020-06-18' }
}

Related

How do I convert this SQL query that uses row value comparison into a sequelize query?

I have this SQL query:
SELECT *
FROM funds
WHERE (fund_id, created_at) > ($1, $2)
ORDER BY created_at DESC
LIMIT 5;
...that I am trying to convert into a sequelize (v6) filter object for the findAll(...) query.
I have an index for (fund_id, created_at) and I am using sqlite as the database.
My objective with the query is to be able to use keyset pagination using (fund_id, created_at).
So far this is what I have:
{
where: {
[Op.and]: [
{ fundId: { [Op.gt]: prev_fund_id } },
{ createdAt: { [Op.gt]: prev_created_at } },
],
},
limit: 5,
order: [["created_at", "DESC"]],
}
This doesn't exactly convert into the expected SQL query I mentioned above as shown by the log of the SQL query passed to my sqlite database:
SELECT `fund_id`, `name`, `description`, `created_at`, `updated_at` FROM `funds` WHERE (`fund_id` > '04e5b202-e62e-417a-b9d8-8cd5b6a1cb8f' AND `created_at` > '2023-02-13 07:38:36.683 +00:00') ORDER BY `created_at` DESC LIMIT 5;
The headache that I am running into is converting the (fund_id, created_at) > ($1, $2) expression...
I am fairly new to SQL and I believe (correct me if I am wrong) that (fund_id, created_at) is not equivalent to using the AND logical operator in SQL. Yet sequelize doesn't seem to have any operators (Op) for that expression...
How should I use sequelize to create this query?
const { Op } = require("sequelize");
Fund.findAll({
where: {
[Op.and]: [
{ fund_id: { [Op.gt]: $1 } },
{ created_at: { [Op.gt]: $2 } },
],
},
order: [["created_at", "DESC"]],
limit: 5,
})
.then(funds => {
// handle the results
})
.catch(error => {
// handle the error
});
I hope I understood well what you want to do

Prisma client query for latest values of each user

I am new to prisma-client and I want to return the latest value register by each user of a given company.
This is my schema.prisma:
model Locations {
id Int #id #default(autoincrement())
user String
company String
latitude String
longitude String
timestamp String
}
This is what I have tried so far:
const lastLocations = await db.locations.findMany({
where: {
company,
},
orderBy: {
id: 'desc',
},
take: 1,
});
But I need to get 1 value for each user, I solved this previously in sql with:
WITH ranked_messages AS ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY userID ORDER BY timestamp DESC) AS rn FROM locations AS m ) SELECT * FROM ranked_messages WHERE rn = 1 AND companyID = "${companyID}";`;
But I have no idea how to do proceed in prisma. Is there an "each" method?
I appreciate any help. Thank you.
I solved using distinct option:
const lastLocations = await db.locations.findMany({
where: {
company,
},
distinct: ['user'],
orderBy: {
id: 'desc',
},
});
Thanks.

How to query for a null fields with graphql?

I'm trying to query for a field that can be null or its _gt, but cannot find a way to make this work.
I've tried this:
query GetBanner {
foo(
sort: "posicao:asc",
where: {
startDate_lt: "2021-10-13T21:13:16.510Z",
_or: [
{ endDate_gt: "2021-10-13T21:13:16.510Z"},
{ endDate: null }
]
}
) {
id
created_at
updated_at
startDate
endDate
}
}
But I'm getting the following error message:
Invalid format, expected a timestamp or an ISO date
How to properly query this?

Convert MySQL "where" to Sequelizejs "where"

I was trying to write "WHERE (CASE ... THEN ... ELSE ... END) > 0" to sequelize v3.33 but couldn't find the solution yet.
Had tried sequelize.literal('...') but didn't work.
Using "HAVING" is one of the solutions but it's no good for performance-wise for large data extraction and it's twice as slow.
This is just an example of MySQL code but pretty much close to what I want to achieve.
SELECT
(CASE `a`.`fee` IS NULL
THEN `a.b`.`fee`
ELSE `a`.`fee`
END) AS `_fee`
FROM `a`
WHERE
(CASE `a`.`fee` IS NULL
THEN `a.b`.`fee`
ELSE `a`.`fee`
END) > 0 AND
(created_at > currentDate
AND
created_at < futureDate)
I want to convert this to sequelize. Below is as far as I can go, I don't know how to add that case closure.
models.a.findAll({
...
where: {
created_at: { $gt: startDate, $lt: endDate }
}
})
*** Don't mind about created_at, it's just an example.
You can use sequelize.where and sequelize.literal for that :
where:{
$and : [
{ created_at: { $gt: startDate, $lt: endDate } },
sequelize.where(sequelize.literal('(CASE `a`.`fee` IS NULL THEN `a.b`.`fee` ELSE `a`.`fee` END)') , { $gt : 0 } )
]
}
Note : this might not work as alias a. of the table might be diff, you can debug and change as per your query

Sequelize cast column to integer in where clause

Trying to cast a column inside a where clause to search for a query against. Have a difficult time finding reliable documentation on how to do this. Any ideas?
return await User.findAndCountAll({
where: {
[Op.or]: {
'email': { [Op.iLike]: `%${query}%` },
'$id::text$': { [Op.iLike]: `%${query}%` } // id is int but needs to be string for searching
}
},
limit,
offset: page * limit,
order: [[sortBy, sortOrder.toUpperCase()]],
raw: true,
logging: console.log
});
I think this is what you searching for:
where: {
[Op.or]: [
{email: {[Op.iLike]: `%${query}%`}},
sequelize.where(
sequelize.cast(sequelize.col('User.id'), 'varchar'),
{[Op.iLike]: `%${query}%`}
),
],
},
As #leogoesger's answer didn't work for JSONB fields in Postgres, I tried this:
where: {
["data.createdAt::timestamp"]: {
[Op.lt]: "now() - interval '3 days'"
}
}
Lo and behold, it produced:
WHERE CAST(("User"."data"#>>'{createdAt}') AS TIMESTAMP) < now() - interval '3 days'
Using Sequelize 5.1.0.
This worked for me:
Notification.findOne({ where: {
[Op.and]: [
sequelize.literal("cast(notify_data as CHAR) = "+game_id),
{user: players[i].user, notify_type: type.id}
]
}});
Basically, sequelize.literal returns a string rather than a key-value pair, so I did a work around using Op.and which can take both strings and objects in its array
order: [sequelize.col('id')],
where:
sequelize.where(
sequelize.cast(sequelize.col('id'), 'varchar'),
{ [Op.iLike]: `%${filter}%` },
),
// matches all rows using id and fetching results in order (casts integer column to string)

Categories

Resources