sequelize aggregate group by not working as I want - mysql

I want to fetch Votes Info with relations in a group according to audioId, but my code not working as aspected. 'user. id' break the group, and showing one by one vote.
what is the problem with my code? and how to group with only audioId and also fetch related Data
try {
const votes = await globalVotes.findAll({
group: ['audioId', 'mediaType', 'audio.id', 'user.id'],
attributes: [
'audioId',
'mediaType',
[Sequelize.fn('SUM', Sequelize.col('totalVote')), 'total_vote'],
[Sequelize.fn('MAX', Sequelize.col('voterEmail')), 'latest_email'],
[Sequelize.fn('COUNT', Sequelize.col('voteCount')), 'total_vote_count'],
[Sequelize.fn('MAX', Sequelize.col('vottingNum')), 'latest_number'],
[Sequelize.fn('MAX', Sequelize.col('globalVotes.user_Id')), 'latest_user'],
[
Sequelize.fn('MAX', Sequelize.col('globalVotes.updatedAt')),
'latest_time',
],
],
include: [
{
model: Audio,
attributes: ['aTitle', 'aImage', 'audioFolderId'],
include: [
{
model: AudioFolder,
attributes: ['folderName'],
},
],
group: ['audioFolderId.id'],
},
{
model: User,
attributes: ['fullName'],
},
],
order: [[Sequelize.fn('SUM', Sequelize.col('totalVote')), 'DESC']],
raw: true,
nest: true,
});
console.log(votes);
res.status(200).render('admin/chart/audio/index', {
title: 'Manage Audio Votes',
votes,
});
hope i get some info,

Related

convert sql query to sequelize

I can't convert the query I wrote the sql query to sequelize.
This is the query I want to convert;
SELECT
sum(document_details.qty)'miktar',
stocks.id,
stocks.`name`
FROM
document_details
INNER JOIN documents ON documents.id = document_details.document_id
INNER JOIN stocks ON document_details.stock_id = stocks.id
WHERE documents.warehouse_id = 1
GROUP BY document_details.stock_id
This is the query I wrote. However, I only get one data. The output must come in more than one
const {id} = req.query;
const {limit, page, sortColumn, sortType, search} = req.body;
Documents.hasMany(DocumentsDetail, {foreignKey: "document_id"})
DocumentsDetail.belongsTo(Stocks, {foreignKey: "stock_id"});
const DocumentsList = await Documents.findAll({
limit: limit,
offset: (page - 1) * limit,
order: [
[sortColumn, sortType]
],
where: {
[Op.and]: [
{
warehouse_id: id
},
{
id: {
[Op.substring]: [
search
]
}
},
],
},
include: [
{
model: DocumentsDetail,
attributes: [
"stock_id",
"name",
[sequelize.fn('sum', sequelize.col('qty')), 'total'],
],
group: ["stock_id"]
},
],
});
res.json({
total: total.length,
data: DocumentsList,
warehouse_name
});
How can I fix? Or what is the truth? can you help?
This is how I solved my question. Hope it helps someone else too..
DocumentsDetail.belongsTo(Documents, {foreignKey: "document_id"})
DocumentsDetail.belongsTo(Stocks, {foreignKey: "stock_id"});
await DocumentsDetail.findAll({
attributes: [
[sequelize.fn('sum', sequelize.col('qty')), 'quantity'],
],
where: {
"$document.warehouse_id$": id,
},
include: [
{
model: Documents,
},
{
model: Stocks,
},
],
group: ["stock_id"],
}).then((data) => {
let opt = {
total: data.length,
data: warehouse_name,
warehouse: data
}
res.json(opt);
})

Sequelize group by a field which is not selected in attributes

Here is my query:
await models.advisorCheckModel.findAll({
include: {
model: models.advisorModel,
as: 'advisor',
attributes: [
['advisorFirstName', 'firstName'],
['advisorLastName', 'lastName']
]
},
where: {
userId: user.id,
advisorCheckCreateTime: {
[Op.between]: [startDay, endDay]
}
},
attributes: [
[fn('MIN', col('advisorCheckCreateTime')), 'time'],
// 'advisorId'
],
group: [
[fn('from_unixtime', col('advisorCheckCreateTime'), '%Y-%m-%d %h')],
'advisorId'
],
})
and i got this error:
Column 'advisorId' in group statement is ambiguous
Is there any way to group with advisorId column which is not selected in attributes?

How to limit includes on a belongsToMany association in Sequelize JS?

I currently have the following models in Sequelize:
Product
and
ProductList.belongsToMany(models.Product, { as: 'products', through:
sequelize.models.ProductListProduct, foreignKey: 'productListId'});
and the pivot, ProductListProduct
I am currently trying to get a series of productList to show on my homepage,
and would need to limit the returned products to a certain value (6 in this case):
let productLists = await ProductList.findAll({
where: {
slug: ['recommended', 'new_and_promos']
},
include: [{
model: Product,
as: 'products',
include: ['attributes', 'images'],
where: {
active: true
}
}],
order: [
[
'products', ProductListProduct, 'position', 'ASC'
]
]
})
This is the current fetch, however if I add a limit to the include, it tells me that only hasMany can have {separate: true} ;
To recap, what I'm trying to achieve is to return n ProductList, each with just m Product attached.
Managed to get it working like this, doesn't look ideal but it does the job:
let productLists = await ProductList.findAll({
where: {
slug: ['recommended', 'new_and_promos']
},
include: [{
model: Product,
as: 'products',
include: ['attributes', 'images'],
where: Sequelize.literal('`products->ProductListProduct`.`position` < 8')
}],
order: [
[
'products', ProductListProduct, 'position', 'ASC'
]
]
})

How to fix Sequelize nested includes not working with limit/order/attributes?

I've got some models that have associations with each other, and I need to grab them all in a certain request. I need to use limit, order, and attributes on basically all parts of it, but this is causing the nested includes to freak out and I'm not entirely sure what's wrong with it.
It doesn't really print any errors or anything, the models either just don't get included in the response (i.e they are empty.), or they get included but stuff like order/limit is ignored.
I've already tried using subQuery, separate, etc... None of those worked.
The query in question;
const categories = await models.Category.findAll({
attributes: ['id', 'title', 'description'],
order: [['title', 'ASC']],
include: [
{
model: models.Product,
attributes: ['id', 'title'],
through: { attributes: [] },
include: [
{
model: models.Price,
attributes: ['id', 'amount', 'createdAt'],
order: [['createdAt', 'DESC']],
limit: 1,
},
],
},
],
});
The associations;
models.Category.belongsToMany(models.Product);
models.Product.belongsToMany(models.Category);
models.Product.hasMany(models.Price);
models.Price.belongsTo(models.Product);
I ideally want the query provided above to return;
Category with the order of Ascending based on title.
Product inside of Category with the attributes id and title.
Price inside of Product with the attributes id, amount, and createdAt, the order of Descending based on createdAt, and with a limit of 1.
In order to get the query to sort by Product.Price.createdAt, add [models.Product, models.Price, 'createdAt', 'DESC'] to order. As far as limiting: in order to limit the included model, you need to run it as a separate query, so add separate: true to the include.
Code:
const categories = await models.Category.findAll({
attributes: ['id', 'title', 'description'],
order: [['title', 'ASC'], [models.Product, models.Price, 'createdAt', 'DESC']],
include: [
{
model: models.Product,
attributes: ['id', 'title'],
through: { attributes: [] },
include: [
{
model: models.Price,
attributes: ['id', 'amount', 'createdAt'],
separate: true,
limit: 1,
},
],
},
],
});

Sequelize include even if it's null

I am using Sequelize express with Node.js as the backend, some data from my sequelize I need to include to another table but some of these data is null so the whole result I’m getting is null.
Question: how can I return some data if data it's available and return the other null if not data is there
router.get("/scheduled/:id", function(req, res, next) {
models.Order.findOne({
where: {
id: req.params.id
},
attributes: ['orderStatus', 'id', 'serviceId', 'orderDescription', 'orderScheduledDate'],
include: [{
model: models.User,
attributes: ['firstName', 'phoneNumber']
}]
}).then(function(data) {
res.status(200).send({
data: data,
serviceName: data["serviceId"]
});
});
});
I want: the result should return null if there is no user for the order and return order details and user when it is null.
However, a where clause on a related model will create an inner join and return only the instances that have matching sub-models. To return all parent instances, you should add required: false for more detail check nested-eager-loading
var users = require('./database/models').user;
models.Order.findOne({
where: {
id: req.params.id
},attributes: ['orderStatus','id','serviceId','orderDescription','orderScheduledDate'],
include: [
{model: users,required: false,
attributes: ['firstName','phoneNumber']
}
]
}).then(function(data) {
res.status(200).send({data : data,serviceName : data["serviceId"]});
});
You can add attribute required: false,
const result = await company.findAndCountAll({
where: conditions,
distinct: true,
include: [
media,
{
model: tag,
where: tagCond,
},
{ model: users, where: userCond, attributes: ['id'] },
{
model: category_company,
as: 'categoryCompany',
where: categoryCond,
},
{ model: media, as: 'logoInfo' },
{ model: city, as: 'city' },
{
model: employee,
as: 'employees',
required: false,
include: [{
model: media,
as: 'avatarInfo',
}],
where: {
publish: {
[Op.ne]: -1,
},
},
},
],
order: [['createdAt', 'DESC']],
...paginate({ currentPage: page, pageSize: limit }),
});