How to write subquery with multiple where in sequelize using NodeJS - mysql

I need to execute this query using sequelize.
select * from mysqlDB.songTable where
X in (SELECT X FROM movieDB4.songTable where Y like('%pencil%') and Z='title') and
Y='tam' and Z='language';
I tried like this. but it throws some invalid value[object] error. please help to resolve this query.
const tempSQL = sequelize.dialect.QueryGenerator.selectQuery('songTable',{
attributes: ['X'],
where: {
Y: {$like: '%'+text[i]},
Z: "content_title"
}})
.slice(0,-1); // to remove the ';' from the end of the SQL
User.findAll({
where: {
X: {
$in: sequelize.literal('(' + tempSQL + ')'),
$and: {Y: lang.substring(0,3),
Z: 'language'}
}
}
})

You can use sequelize.query() to execute raw queries.
Example
return this.sequelize.query(`SELECT category_id, category_name from table_categories where category_id in (SELECT DISTINCT category_id from table_authorized_service_center_details where center_id in (SELECT center_id from table_authorized_service_center where brand_id ${condition}));`).then((results) => {
if (results.length === 0) {
reply({status: true, categories: [], forceUpdate: request.pre.forceUpdate});
} else {
reply({status: true, categories: results[0], forceUpdate: request.pre.forceUpdate});
}
}).catch((err) => {
console.log(err);
reply({status: false, message: "ISE"});
});

Related

Fetch all records from table A where id = somvalue in B plus records which don't have id in B

I have two tables a coupons table and a coupon_city_map table.
id
coupon_code
1
OFFER20
2
OFFER10
3
OFFER50
4
OFFER40
5
OFFER90
coupon_Id
city_id
1
2
2
3
3
4
4
2
I need coupons with ids 1 4, and 5 for city_id = 2.
So It should fetch all the coupons where city_id=2 i.e. coupons with id 1 and 4
and it should also fetch coupons which don't have key in coupon_city_map i.e 5.
This is what I have tried but the query in [Op.or] is not working, and it returns all the coupons instead.
let coupons = await Coupon.findAll({
where: {
[Op.or]: [
{ '$CouponCities.city_id$': city_id },
{ '$CouponCities.coupon_id$': null },
],
...filters // other filter like is_active: true
},
include: {
model: CouponCity,
attributes: [],
},
attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount', 'discount_upto', 'description', 'display'],
});
The query being generated
SELECT `Coupon`.`id`,
`Coupon`.`coupon_code`,
`Coupon`.`discount_per`,
`Coupon`.`flat_discount`,
`Coupon`.`discount_upto`,
`Coupon`.`description`,
`Coupon`.`display`
FROM `coupons` AS `Coupon`
LEFT OUTER JOIN `coupon_city_map` AS `CouponCities` ON `Coupon`.`id` = `CouponCities`.`coupon_id`
WHERE (`Coupon`.`user_id` IS NULL OR `Coupon`.`user_id` = 1)
AND `Coupon`.`is_active` = true
AND `Coupon`.`is_external` = false
AND `Coupon`.`start_date` < '2020-12-30 10:33:20'
AND `Coupon`.`expiry_date` > '2020-12-30 10:33:20';
Update
I also tried below, but still it is returning all the coupons.
let coupons = await Coupon.findAll({
// where: {
// ...filters,
// },
include: {
model: CouponCity,
required: false,
where: {
[Op.or]: [
{
zone_id: zoneId,
}, {
coupon_id: null,
},
],
},
attributes: [],
},
attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount','discount_upto', 'description', 'display'],
});
...and it generates below query.
SELECT `Coupon`.`id`,
`Coupon`.`coupon_code`,
`Coupon`.`discount_per`,
`Coupon`.`flat_discount`,
`Coupon`.`discount_upto`,
`Coupon`.`description`,
`Coupon`.`display`
FROM `coupons` AS `Coupon`
LEFT OUTER JOIN `coupon_city_map` AS `CouponCities`
ON `Coupon`.`id` = `CouponCities`.`coupon_id`
AND ( `CouponCities`.`zone_id` = 1
AND `CouponCities`.`coupon_id` IS NULL )
WHERE `Coupon`.`is_active` = true
AND `Coupon`.`is_external` = false;
This is what worked for me, query is mess but it works. I am posting all the codes for better understanding for anyone interested.
Here zone is city.
{
const filters = {
start_date: {
[Op.lt]: new Date(),
},
expiry_date: {
[Op.gt]: new Date(),
},
};
if (userId) {
filters[Op.or] = [{
user_id: null,
}, {
user_id: userId,
}];
filters[Op.and] = {
[Op.or]: [
sequelize.literal('CouponZones.zone_id = 1'),
sequelize.literal('CouponZones.coupon_id IS null')
],
};
} else {
filters.user_id = null;
}
let coupons = await Coupon.findAll({
where: {
...filters,
},
include: {
model: CouponZone,
attributes: [],
},
attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount', 'discount_upto', 'description', 'display'],
});
This is the query it generates.
SELECT `Coupon`.`id`,
`Coupon`.`coupon_code`,
`Coupon`.`discount_per`,
`Coupon`.`flat_discount`,
`Coupon`.`discount_upto`,
`Coupon`.`description`,
`Coupon`.`display`
FROM `coupons` AS `Coupon`
LEFT OUTER JOIN `coupon_zone_map` AS `CouponZones`
ON `Coupon`.`id` = `CouponZones`.`coupon_id`
WHERE ( `Coupon`.`user_id` IS NULL
OR `Coupon`.`user_id` = 1 )
AND ((CouponZones.zone_id = 1 OR CouponZones.coupon_id IS null))
AND `Coupon`.`is_active` = true
AND `Coupon`.`is_external` = false;
Use UNION
You can write query like below
SELECT coupons.*
FROM coupons,
coupon_city_map
WHERE coupons.id = coupon_city_map.coupon_id
AND coupon_city_map.city_id = 2
UNION
SELECT coupons.*
FROM coupons
WHERE coupons.id NOT IN(SELECT coupon_city_map.coupon_id
FROM coupon_city_map)

How to fetch a serial number from a mysql table using Sequelize in nodeJS?

I have a mysql Query:-
SELECT #a:=#a+1 serial_number,rule FROM pledges,(SELECT #a:= 0) AS a;
This gives me a serial number along with the rule from the table.
How can I do that in Sequelize?
This is the query I wrote in the model which gives me id and rule:-
Pledge.getPledgeList = function(lang_code='EN') {
return this.findAll({
attributes:['id','rule'],
where: {
status:'a',
deleted_at:null
},
include:[
{ association: 'local', where: {lang_code:lang_code} ,required: false},
]
})
}

sequelize query that implements calculation using provided value and table row value

equivalent sequelize query for the following raw query:
SELECT
*,
(distance1 - table.distance) as distance
FROM
table
HAVING
distance >= 100;
Translation.findAll({
attributes: { include: [[models.sequelize.fn('LENGTH', models.sequelize.col('value')), 'total']] },
having: {total: {lte: 10}}
}).then(function(result) {
result.forEach(function(t) {
...
});
})
is equivalent to
SELECT *, LENGTH(`value`) AS `total`
FROM `content_translation`
HAVING `total` <= 10;
And works.
I think you should have somthing like
table.findAll({
attributes: { include: [['(distance1 - distance)', 'distance']] },
having: {distance: {gte: 10}}
}).then(function(result) {
result.forEach(function(t) {
...
});
})
http://docs.sequelizejs.com/en/latest/api/model/#findalloptions-promisearrayinstance

running a query on each iteration

Can somebody help me with this query on a returned query?
I want the query to iterate through the results of the previous query to see if a voucher has been used
this is the code for the query :
db.query('SELECT * FROM Table WHERE ID in ?', [(1,2,3,4)],
function(err, rows) {
if (err) throw err
var items = []
rows.forEach(function(i) {
var item = {
'item1': i.item1,
'item2': i.item2,
'item3': i.item3
}
db.query('SELECT * FROM Table2 WHERE ID = ?', [i.ID],
function(err, rows2) {
if (err) throw err
item.subvalue = rows2
})
items.push(item)
})
res.json(items)
})
So I did this in the end. used multiple statement where the second query returns all possible results need for results in query 1. Then I can iterate through results 1 and results 2 within it.
Still not sure this is the best approach but it works. Any suggestions are very welcome
db.query('SELECT 1 WHERE Range ?; SELECT 2 WHERE ID IN (SELECT 1)',
[req.body.hotelid, '2015-11-01', '2015-11-30',
req.body.hotelid, '2015-11-01', '2015-11-30'],
function(err, result) {
if (err) console.log(err)
else
var items = []
result[0].forEach(function(i) {
var giftVoucherUsed = []
var item = {
'ID': i.BookingID,
'BookingDate': i.BookingDate,
'GuestName': 'Guestname'
}
result[1].forEach(function(g){
if(g.BookingID == i.BookingID){
giftVoucherUsed.push(g)
}
})
item['GiftVoucher'] = giftVoucherUsed
items.push(item)
})
res.json(items)
});

Nodejs JOIN query: formatting JSON output

I'm making a pretty simple RIGHT JOIN query, but I can't format the output correctly.
Here is the Query:
connection.query({sql : "SELECT users.*, rides.* FROM users RIGHT JOIN rides ON users.id = rides.id_user WHERE users.id = ?", nestTables: '_', values : [id] }, function(err, rows){
console.log(rows);
});
This is the output I have:
[ { users_id: 52,
users_firstname: 'greg', //End first table data
rides_latitude: '50.847454', //Second table data: row 1
rides_longitude: '4.358356',
},
{ users_id: 52,
users_firstname: 'greg', //Exactly the same first table data
rides_latitude: '50.9', //Second table data: row 2
rides_longitude: '4.4',
} ]
And this is the ouput I would like to have:
[ { users_id: 52,
users_firstname: 'greg',
rides : [
{
rides_latitude: '50.847454',
rides_longitude: '4.358356'
},
{
rides_latitude: '50.9',
rides_longitude: '4.4'
}
]
}]
I tried nestTables as you can see,
Wrapped for legibility:
connection.query({
sql : "SELECT \
users.users_id, \
users.users_firstname, \
rides.rides_latitude, \
rides.rides_longitude \
FROM \
users \
RIGHT JOIN rides ON users.id = rides.id_user \
WHERE \
users.id = ?",
nestTables: '_',
values : [id]
}, function (err, rows) {
var result = [], index = {};
if (err) throw err;
rows.forEach(function (row) {
if ( !(row.users_id in index) ) {
index[row.users_id] = {
users_id: row.users_id,
users_firstname: row.users_firstname,
rides: []
};
result.push(index[row.users_id]);
}
index[row.users_id].rides.push({
rides_latitude: row.rides_latitude,
rides_longitude: row.rides_longitude
});
});
console.log(result);
});