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
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
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.
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?
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
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)