How do I select a value as a column in sequelize - node.js

How do I perform sql query such as this SELECT 'OLD' AS CUSTOM_COLUMN FROM TABLE in sequelize?

You can use sequelize.literal for that.
const response = await YourModel.findAll({
where: {
...attributes
},
attributes: [
'column_name_on_model',
[sequelize.literal("'OLD'"), 'CUSTOM_COLUMN'], //custom column name
],
raw: true
});

If you've set up a model for your table, you can alias the column in the model definition:
{
CUSTOM_COLUMN: {
type: Sequelize.STRING,
field: 'OLD'
}
}
And then limit a find query to that column:
MyModel.find all({ attributes: ['CUSTOM_COLUMN'] })
(See http://sequelize.readthedocs.io/en/v3/docs/models-definition/)

Related

How Can I write INNER Join query using Sequelize on Node.js

I have two tables. One is tblEmailAuditLog having columns Id, OrderId, Body, CommunicationType, CreatedOn, Reciever, WorkflowStatusId, IsSuccess another one is tblLookUp having column names as LU_LookUpValue and LU_LOOKUPID. I want to join the two tables based on the columns (CommunicationType and LU_LOOKUPID)
My inner join query looks as below:
select Id, OrderId, Body, CommunicationType, CreatedOn, Reciever, WorkflowStatusId, IsSuccess, LU_LookUpValue from tblEmailAuditLog INNER JOIN tblLookUp on tblEmailAuditLog.CommunicationType = tblLookUp.LU_LOOKUPID;
I am trying to write the above query using sequelize ORM.
I have tried the below things.
1.
let auditLogs = await MediMarket.TblEmailAuditLog.findAll({
include: [
{
model: MediMarket.TblLookUp,
required: true,
where: { orderId: req.body.orderId },
},
],
});
2.
let auditLogs = MediMarket.TblEmailAuditLog.hasMany(
MediMarket.TblLookUp,
{ foreignKey: "CommunicationType" }
);
MediMarket.TblLookUp.belongsTo(MediMarket.TblEmailAuditLog, {
foreignKey: "LU_LOOKUPID",
});
MediMarket.TblEmailAuditLog.findAll({
where: { orderId: req.body.orderId },
include: [MediMarket.TblLookUp],
});
But it is not giving the expected result.

Sequelize - query on model and related model - OR

i'm pretty new to Sequelize. I have a scenario in which I want to retrieve records from the DB with filters on the desired model records and his related records. I need to find records that answer the query with properties on the "main" model OR records that answer the query on the related field.
let customers = await db.customers.findAll({
where: {
location: locationId,
some_kind_of_string_identifier: someKindOfStringIdentifier
},
include: [
{
model: db.users,
where: db.sequelize.where(
db.sequelize.fn(
'concat',
db.sequelize.col('first_name'),
' ',
db.sequelize.col('last_name'),
),
db.sequelize.Op.like,
`%${query}%`,
),
},
],
});
So in the example above I have a free text search query (query variable), and I want to get all customers with name like query OR that has "someKindOfStringIdentifier" which matches query.
Is there a way to do so?
I'd try the following:
customers.findAll({
where: {
$and: [{ location: locationId },
{ $or: [{ some_kind_of_string_identifier: someKindOfStringIdentifier },
Sequelize.where(
Sequelize.fn('concat',
Sequelize.col('$db.users.first_name$'), ' ', Sequelize.col('$db.users.last_name$')),
{ like: '%' + query + '%' }
)]
}]
},
include: [{
model: db.users,
required: false
}]
});
Ref: https://stackoverflow.com/a/36287978/5430833, Sequelize: Concat fields in WHERE LIKE clause
Right now, you are effectively doing the WHERE when doing a join. This is not what you want. You want to JOIN both tables (customers and users) and then apply WHERE with your or condition, right?
Above code is untested, but I believe you've got to apply condition in findAll, not the include.

Inner join query in Sequelize referencing multiple tables

HOW DO I WRITE BELOW QUERY IN SEQUELIZE?
select vdc_id,vdc.name as vdc,
districts.name as district,
states.name as state,
countries.name as country
from vdc
INNER JOIN districts on (vdc.district_id=districts.district_id and vdc.name like 'L%')
INNER JOIN states on (districts.state_id=states.state_id)
INNER JOIN countries on (states.country_id=countries.country_id)
order by district asc;
Associations :
vdc table contains fk_district_id
db.vdc.belongsTo(db.districts,{
foreignKey:"district_id"
})
db.districts.hasMany(db.vdc,{
foreignKey:"district_id"
})
districts table contains fk_state_id
db.districts.belongsTo(db.states,{
foreignKey:"state_id"
})
db.states.hasMany(db.districts,{
foreignKey:"state_id"
})
states table contains fk_country_id
db.states.belongsTo(db.countries,{
foreignKey:"country_id"
})
db.countries.hasMany(db.states,{
foreignKey:"country_id"
})
THANKS YOU!
It seems you would need something like the code below. You would need to adjust it to work with your models since they were not provided, but this should give you an idea of what is required to get the query you want.
vdc.findAll({
attributes: ['vcd_id', 'name'],
include: [
{
model: 'districts', // Or districts model
attributes: [['name', 'district']], // name as district
required: true, // Use inner join instead of left join
on: { // Join on district id and name like 'L%'
'district_id': { [Op.eq]: sequelize.col('districts.district_id') },
'name': { [Op.like]: 'L%' }
}
},
// Custom join shouldn't be necessary for the following due to foreign key config
{
model: 'states',
attributes: [['name', 'state']],
required: true
},
{
model: 'countries',
attributes: [['name', 'country']],
required: true
}
],
order: [['district', 'ASC']]
});

How to count a group by query in NodeJS Sequelize

In Rails I can perform a simple ORM query for the number of Likes a model has:
#records = Model
.select( 'model.*' )
.select( 'count(likes.*) as likes_count' )
.joins( 'LEFT JOIN likes ON model.id = likes.model_id' )
.group( 'model.id' )
This generates the query:
SELECT models.*, count(likes.*) as likes_count
FROM "models" JOIN likes ON models.id = likes.model_id
GROUP BY models.id
In Node Sequelize, any attempt at doing something similar fails:
return Model.findAll({
group: [ '"Model".id' ],
attributes: ['id', [Sequelize.fn('count', Sequelize.col('"Likes".id')), 'likes_count']],
include: [{ attributes: [], model: Like }],
});
This generates the query:
SELECT
Model.id,
count(Likes.id) AS likes_count,
Likes.id AS Likes.id # Bad!
FROM Models AS Model
LEFT OUTER JOIN Likes
AS Likes
ON Model.id = Likes.model_id
GROUP BY Model.id;
Which generates the error:
column "Likes.id" must appear in the GROUP BY clause or be used in an aggregate function
It's erroneously selecting likes.id, and I have no idea why, nor how to get rid of it.
This sequelize github issue looks totally like your case:
User.findAll({
attributes: ['User.*', 'Post.*', [sequelize.fn('COUNT', 'Post.id'), 'PostCount']],
include: [Post]
});
To resolve this problem we Need to upgrade to latest version of sequelize and include raw = true,
Here is How I had done after lot of iteration and off-course googling.
getUserProjectCount: function (req, res) {
Project.findAll(
{
attributes: ['User.username', [sequelize.fn('COUNT', sequelize.col('Project.id')), 'ProjectCount']],
include: [
{
model: User,
attributes: [],
include: []
}
],
group: ['User.username'],
raw:true
}
).then(function (projects) {
res.send(projects);
});
}
where my reference models are
//user
var User = sequelize.define("User", {
username: Sequelize.STRING,
password: Sequelize.STRING
});
//project
var Project = sequelize.define("Project", {
name: Sequelize.STRING,
UserId:{
type:Sequelize.INTEGER,
references: {
model: User,
key: "id"
}
}
});
Project.belongsTo(User);
User.hasMany(Project);
after migration ORM create 'Users' & 'Projects' table into my postgres server.
Here is SQL Query by ORM
SELECT
"User"."username", COUNT("Project"."id") AS "ProjectCount"
FROM
"Projects" AS "Project"
LEFT OUTER JOIN "Users" AS "User" ON "Project"."UserId" = "User"."id"
GROUP BY
"User"."username";
What worked for me counting column A and grouping by column B
const noListingsPerRetailer = Listing.findAll({
attributes: [
'columnA',
[sequelize.fn('COUNT', sequelize.col('columnB')), 'labelForCountColumn'],
],
group:["columnA"]
});

How to do query based on "date" column in sqlite3 using sequelize?

I'm using Sequelize with sqlite3 but having trouble querying data based on "date" type columns.
Here is my model definition:
var sensorData = sequelize.define('Data',
{
time: Sequelize.DATE,
value: Sequelize.FLOAT,
type: Sequelize.STRING,
source: Sequelize.STRING
},
{
timestamps : false
});
Now I want to get all the records with 'time' later than a given time in this function:
function selectData(start_date, num_of_records, callback)
{
sensorData.findAll({
limit: num_of_records,
where: [time, '???'], <====== How to specify the condition here?
order: 'time'}).success(callback);
}
I can't find any thing on Sequelize's website about 'date' type based query statement.
Any idea?
Just like Soumya says, you can use $gt, $lt, $gte or $lte with a date:
model.findAll({
where: {
start_datetime: {
$gte: new Date()
}
}
})
You can use sequelize.fn like this:
where:{timestamp: gte:sequelize.fn('date_format', fromDate, '%Y-%m-%dT%H:%i:%s')
,lte:sequelize.fn('date_format', toDate, '%Y-%m-%dT%H:%i:%s')
}

Resources