How to get the intersection of 2 mysql queries? - javascript

Suppose I have a MySQL table which looks like this:
Each job in the table contains 3 tasks.
How can I get all the JobIds whose taskA is in Done state and taskB is in New state?
In my case, I want a query which returns qwert, and zxcv.
I've come up with this query:
select JobId from MyTable where TaskSeq=0 and TaskState='Done'
intersect
select JobId from MyTable where TaskSeq=1 and TaskState='New';
but my version of MySQL doesn't support the intercept operator.
My ultimate goal is to write the query in sequelize. But I think I should know the MySQL query first so that I can create a sequlize query.
And I also wish that the sequlize query can be done in 1 function instead of multiple functions concatenated with then.
Here's the SQL Fiddle to help you try the table.

You could just use a join:
select mt.JobId
from MyTable mt
join MyTable mt2 on mt2.JobId = mt.JobId
where mt.TaskSeq = 0 and mt.TaskState = 'Done' and mt2.TaskSeq = 1 and mt2.TaskState = 'New'
Here's an attempt at Sequelize on this query, however this is a guess. Hopefully it gives you something to work with:
MyTable.findAll({
attributes: ['JobId', 'TaskSeq', 'TaskState'],
include: [{
model: MyTable,
attributes: ['JobId', 'TaskSeq', 'TaskState'],
where: {
JobId: Sequelize.col('MyTable.JobId'),
TaskSeq: 1,
TaskState: 'New'
}
}],
where {
TaskSeq: 0,
TaskState: 'Done'
}
});

Related

How to perform mongoose deleteMany() with query operators?

I want to delete X number of posts starting from the most recently created for a specific user.
How can I apply this logic using mongoose so that I can perform just ONE database operation instead of first having to query for these posts and remove them one by one?
I am finding using the query and projection operators with the $ very confusing, any help would be appreciated.
Below I added pseudo code on how it should to work.
Thank you!
const userId = "123456"
const deleteCount = 6
const deletedPosts = await Post.deleteMany({
.where { userid == userId) }
.sort({createdAt: -1}) // delete by most recent
.limit(deleteCount) // only delete 6 (most recent) posts
}, {new: true}) // return results of operation
console.log(deletedPosts.deletedCount) // -> should be "6"
You can't set a limit when using deleteMany or findAndModify. So, if you want to precisely limit the number of documents removed, you'll need to do it in two steps.
db.getCollection('users').find({}, {class : 4}) .limit(2) .sort({StudentAge: -1}) .toArray() .map(function(doc) { return doc._id; }); //returns the array of id's
db.getCollection('users').deleteMany({_id: {$in: [ "s3", "s4" ]}})//put the array of id's

get a range of numbers from sql column of type varchar

I have a postgres server running with one column (say marks) of type VARCHAR(255), but is supposed to have numbers, like if i do a select *.. query , i will get ['100','50','21','14'...] etc.
i would like to run a range query on it, like user passes [10,30] and gets ['21','14'] as result. I think this would require casting at the time of running the BETWEEN query, but i cannot get it to work properly.
I am using sequalize.js which is generating the following query:
SELECT "id"
FROM "token_attributes" AS "token_attributes"
WHERE "token_attributes"."attributesDirectoryId" = 3
AND CAST('token_attributes.attributeValue' AS INTEGER) BETWEEN 10 AND 30;
on server also this query seems to fail. the sequalize query that is being created is :
{
where: {
attributesDirectoryId: 3,
attributeValue: Where { attribute: [Cast], comparator: '=', logic: [Object] }
},
attributes: [ 'id' ]
}
i have used the following code to create the where condition (cast and where were imported from sequelize):
let whereFilter ={}
let value = where(cast(`${tableName}.attributeValue`, 'integer'), {[Op.between]: rangeAsInt})
whereFilter['attributeValue'] = value
so this is basically calling table.findAll({where:whereFilter}) I am not sure how to either make sequelize create a correct sql api or what the actual correct SQL api would be. can anyone help?
found the issue, i missed the sequilize.col function :
let whereFilter ={}
let value = where(cast(col(`${tableName}.attributeValue`), 'integer'), {[Op.between]: rangeAsInt})
whereFilter['attributeValue'] = value
and the query would be :
SELECT "id"
FROM "token_attributes" AS "token_attributes"
WHERE "token_attributes"."attributesDirectoryId" = 3
AND CAST("token_attributes"."attributeValue" AS INTEGER) BETWEEN 10 AND 30;

Mimic where [condition] between [colA] and [colB] sequelize

Looking for assistance in replicating the following mssql operation in sequelize. We have a table with a valid_from and valid_to columns and I need to get todays current date and only return the records that are fall based on that.
I am looking to utilize the .findByPK(), or .findAll() methods in sequelize
SELECT * FROM [table] WHERE GETUTCDATE() BETWEEN f.valid_from AND f.valid_to
I have found the following posts and items with no luck. As they seem to specify two di9ffernt dates between the same column. I need to compare the current UTCDATE between two different columns
Sequelize Query to find all records that falls in between date range
Sequelize query - compare dates in two columns
I was able to simulate but would still like to know if anyone knows how to do the same thing using the between operator
const now = new Date();
return await models.Form.findAll({
where: {
valid_from: {
[Op.lte]: Sequelize.cast(now, 'DATETIMEOFFSET')
},
[Op.and]: {
validTo: {
[Op.gte]: Sequelize.cast(now, 'DATETIMEOFFSET')
}
}
}
});
You can write this query using sequelize.where() to generate the WHERE statement for the BETWEEN operation. For the current timestamp you need to call GETUTCDATE() which we can do via sequelize.fn().
const forms = await models.Form.findAll({
where: {
// create where condition for GETUTCDATE()
sequelize.where(sequelize.fn('GETUTCDATE'), {
// BETWEEN valid_from AND validTo
[Op.between]: [
sequelize.col('valid_from'),
sequelize.col('validTo')
],
}),
},
});
This will generate SQL like:
SELECT * FROM `form`
WHERE GETUTCDATE() BETWEEN `valid_from` AND `validTo`
note that you have underscored valid_from and camelCase validTo in your example.

Fetch the latest data using date in mongodb

I am trying to fetch the latest data from MongoDB in nodejs. let me explain with an example every 2hours I am uploading the data to a collection. when I do a get method I need the latest data how do I do that.
Please help me with this issue.
Here is the Schema
var abc = new mongoose.Schema({
ItemName : String,
date: Date
......
});
This is how I am storing
finalData.push({
ItemName: xyz,
date: new Date()})
abc.insertMany(finalData)
try like this:
your_model_name.find({}).sort('-date').exec(function(err, docs) { ... });
you can sort your collection and get the desired document by limiting the document size to one.
abc.find({}).sort([['date', -1]]).limit(1).exec(function(err, doc) { });
abc.find({}).sort('date').limit(1).then(data=>console.log(data))
criteria can be asc, desc, ascending, descending, 1, or -1
abc.find({}).sort({ field : criteria}).limit(1).exec(function(err, data){ });

Bookshelf change column data type

I`m using bookshelf.js and I want to change the data type column, this is the example I want to do.
select * from table where date(datetime_col) = '2017-03-14'
the datatime_col is DATETIME and I want to convert to date to execute the query.
this is how I'm trying to do in bookshelf
var Model = new model().query(function (qb) {
qb.where('date(datetime_col)', '=' , date);
}).fetchAll()
this is the error when I´m trying to execute the code above
Error: ER_BAD_FIELD_ERROR: Unknown column 'date(datetime_col)' in 'where clause'
This is a full example how can you use knex.raw and bookshelf for query thanks for answer.
Using between two dates with date time column
var Model = new model().query(function (qb) {
qb.whereBetween( Bookshelf.knex.raw("DATE(colum_datetime)"), [date_var1, date_var2]);
}).fetchAll( { withRelated: ['table1', 'table2', {'table3':function (qb) {
qb.orderBy('date_column', 'desc')
}},'table4'] });
Using where
var Model = new model().query("where", Bookshelf.knex.raw("DATE(colum_datetime)"), "=", date_var).fetchAll( { withRelated: ['table1', 'teble2', {'table3':function (qb) {
qb.orderBy('date_column', 'desc')
}},'table4'] });
It looks like that "bookshelf.js" or the underlying "knex" expect to get an attribute name of your model (like datetime_col), and not a sql-fragment like date(datetime_col).
According to this source, you need to pass a part with the function as "raw" sql.
The proposed solution is to write it like this:
model.query("where", Bookshelf.knex.raw("DATE(field) = ?"), "2017-03-04"))

Categories

Resources