Unknown column 'Model1->Model2.fieldname' in 'on clause' - mysql

I have struggling in this error unknown column error.
I have 3 table the following are
Marketplace --- One to Many relationship (marketplace has many products.)
Product --- One to One relationship (Product belongs to marketplace)
Country -- One to many relationship (Country has many products.)
The sample JSON given below :
[{
"id": 1,
"name": "XYZ Name",
"code": "XYZCODE",
"Products": [
{
"id": 150,
"product_name": "ABC",
"product_location": 19,
"state_id": 24,
"city": "California",
"Country": {
"id": 19,
"name": "USA"
}
},
{
"id": 154,
"product_name": "DEF",
"product_location": 19,
"state_id": 24,
"city": "New York",
"Country": {
"id": 19,
"name": "USA"
}
}
]
}]
If am query city and Country name inside the Country table getting following error in sequelize
{
"code": "ER_BAD_FIELD_ERROR",
"errno": 1054,
"sqlState": "42S22",
"sqlMessage": "Unknown column 'Products->Country.name' in 'on clause'",
"sql": "SELECT `MarketplaceType`.`id`, `MarketplaceType`.`name`, `MarketplaceType`.`code`, `Products`.`id` AS `Products.id`, `Products`.`product_name` AS `Products.product_name`, `Products`.`product_location` AS `Products.product_location`, `Products`.`state_id` AS `Products.state_id`, `Products`.`city` AS `Products.city`, `Products->Country`.`id` AS `Products.Country.id`, `Products->Country`.`name` AS `Products.Country.name` FROM `marketplace_type` AS `MarketplaceType` LEFT OUTER JOIN `product` AS `Products` ON `MarketplaceType`.`id` = `Products`.`marketplace_type_id` AND `Products`.`status` = 1 AND `Products`.`marketplace_id` = 1 AND (`Products`.`city` = 'California' OR `Products->Country`.`name` = 'California') LEFT OUTER JOIN `country` AS `Products->Country` ON `Products`.`product_location` = `Products->Country`.`id` WHERE `MarketplaceType`.`status` = 1 AND `MarketplaceType`.`marketplace_id` = 1;"
}
AND MYSQL Query are following :
SELECT `MarketplaceType`.`id`, `MarketplaceType`.`name`, `MarketplaceType`.`code`, `Products`.`id` AS `Products.id`, `Products`.`product_name` AS `Products.product_name`, `Products`.`product_location` AS `Products.product_location`, `Products`.`state_id` AS `Products.state_id`, `Products`.`city` AS `Products.city`, `Products->Country`.`id` AS `Products.Country.id`, `Products->Country`.`name` AS `Products.Country.name` FROM `marketplace_type` AS `MarketplaceType` LEFT OUTER JOIN `product` AS `Products` ON `MarketplaceType`.`id` = `Products`.`marketplace_type_id` AND `Products`.`status` = 1 AND `Products`.`marketplace_id` = 1 AND (`Products`.`city` = 'California' OR `Products->Country`.`name` = 'California') LEFT OUTER JOIN `country` AS `Products->Country` ON `Products`.`product_location` = `Products->Country`.`id` WHERE `MarketplaceType`.`status` = 1 AND `MarketplaceType`.`marketplace_id` = 1;
ORM Query using sequelize :
var marketplaceTypeQueryObj = {};
var productCountQueryParames = {};
marketplaceTypeQueryObj['status'] = status["ACTIVE"];
marketplaceTypeQueryObj['marketplace_id'] = marketplace['WHOLESALE'];
productCountQueryParames['status'] = status["ACTIVE"];
productCountQueryParames['marketplace_id'] = marketplace['WHOLESALE'];
if (req.query.origin) {
productCountQueryParames['$or'] = [{
city: req.query.origin
}, {
'$Products.Country.name$': req.query.origin
}, {
'$Products.State.name$': req.query.origin
}];
}
console.log('productCountQueryParames', productCountQueryParames);
model['MarketplaceType'].findAll({
where: marketplaceTypeQueryObj,
include: [{
model: model['Product'],
where: productCountQueryParames,
include: [{
model: model['Country'],
attributes: ['id', 'name']
}, {
model: model['State'],
attributes: ['id', 'name']
}],
attributes: ['id', 'product_name', 'product_location', 'state_id', 'city'],
required: false
}],
attributes: ['id', 'name', 'code']
})

Change
attributes: ['id', 'product_name', 'product_location', 'state_id', 'city'],
to
attributes: ['id', 'product_name', 'product_location', 'state_id', 'city','country_id'],
Add country id in your product model attributes

Related

Sequlize gives un Wanted info

i have two tables Products and carts and they are many to many relationship across products_carts table
i am getting specific cart and i am including Product with it so i can get the cart and their products
why i am getting products_carts with the products
my sequlize command:
const a = await Cart.findByPk(1,{
attributes: ['id'],
include: {
model: Product,
attributes: ['id'],
},
});
the sql statement :
Executing (default): SELECT `cart`.`id`, `products`.`id` AS `products.id`,
`products->products_carts`.`createdAt` AS `products.products_carts.createdAt`,
`products->products_carts`.`updatedAt` AS `products.products_carts.updatedAt`,
`products->products_carts`.`cartId` AS `products.products_carts.cartId`, `products-
>products_carts`.`productId` AS `products.products_carts.productId` FROM `carts` AS
`cart` LEFT OUTER JOIN ( `products_carts` AS `products->products_carts` INNER JOIN
`products` AS `products` ON `products`.`id` = `products->products_carts`.`productId`) ON
`cart`.`id` = `products->products_carts`.`cartId` WHERE `cart`.`id` = 1;
the ouput i am getting:
{
"cart": {
"id": 1,
"products": [
{
"id": 1,
"products_carts": { // I DONT WANT THIS TO BE SHOWN !!!
"createdAt": "2022-12-25T13:42:16.000Z",
"updatedAt": "2022-12-25T13:42:16.000Z",
"cartId": 1,
"productId": 1
}
}
]
}
}
the relation between them is ..
Cart.belongsToMany(Product, { through: PC });
Product.belongsToMany(Cart, { through: PC });
User.hasOne(Cart);
Cart.belongsTo(User);
PC stands for products_carts
through: { attributes: [] } worked for me

How to join tables and get the json output using jooq

dslContext.select(
jsonObject(
key("id").value(CATEGORY.ID),
key("courses").value(
jsonArrayAgg(
jsonObject(
Arrays.stream(COURSE.fields())
.map(i -> key(CamelcaseConverter.snakeToCamel(i.getName())).value(
i))
.collect(
Collectors.toList())
)
)
)
)
).from(CATEGORY)
.leftJoin(COURSE_CATEGORY).on(CATEGORY.ID.eq(COURSE_CATEGORY.CATEGORY_ID))
.leftJoin(COURSE).on(COURSE.ID.eq(COURSE_CATEGORY.COURSE_ID)).fetchInto(JSONObject.class)
Output I got:
[
{
"courses": [
{
"id": 19
},
{
"id": null
}
],
"name": "Exam1",
"id": 1,
}
]
The required output is
[
{
"courses": [
{
"id": 19
}
],
"name": "Exam1",
"id": 1
},
{
"courses":[],
"name": "Exam2",
"id": 2
}
]
The query which need to be executed is
"select * from category left outer join course_category on category.id = course_category.category_id left outer join course on course_category.course_id = course.id"
how do I implement it?
You forgot to group by:
.groupBy(CATEGORY.ID, CATEGORY.NAME)
If you have a primary (or unique) key on CATEGORY.ID, then in MySQL, it will be sufficient to group by that
.groupBy(CATEGORY.ID)

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 generate query with multiple or condtions in sequelize

I want to query with multiple or conditions in sequelize. Out of two, I have defined only one is reflected in the query generated using sequelize
Current Output:
SELECT `id`, `from_id`, `to_id`, `message`, `format`, `from_type`, `to_type`, `from_deleted_id`, `to_deleted_id`, `created_at`, `updated_at` FROM `messages` AS `Message` WHERE ((`Message`.`from_id` = '1' AND `Message`.`from_type` = 'user') OR
(`Message`.`from_id` = '3' AND `Message`.`from_type` = 'user'))
Expected Output:
SELECT `id`, `from_id`, `to_id`, `message`, `format`, `from_type`, `to_type`, `from_deleted_id`, `to_deleted_id`, `created_at`, `updated_at` FROM `messages` AS `Message` WHERE ((`Message`.`from_id` = '1' AND `Message`.`from_type` = 'user') OR
(`Message`.`from_id` = '3' AND `Message`.`from_type` = 'user')) AND ((`Message`.`to_id` = '1' AND `Message`.`to_type` = 'user') OR
(`Message`.`to_id` = '3' AND `Message`.`to_type` = 'user'))
where object -
where_condition={
[Op.or]: [
{from_id: from_id,from_type:from_type},
{from_id: to_id,from_type:to_type},
],
[Op.or]: [
{to_id: from_id,to_type:from_type},
{to_id: to_id,to_type:to_type},
],
}
Sequlize statement -
models.Message.findAll({where:where_condition})
Where object for having multiple or conditions must be as follow -
where_condition={
[Op.or]: [
{
[Op.and]: [
{
[Op.and]: [{ from_id: from_id }, { from_type: from_type }]
},
{
[Op.and]: [{ from_id: to_id }, { from_type: to_type }]
}
]
},
{
[Op.and]: [
{
[Op.and]: [{ to_id: from_id }, { to_type: from_type }]
},
{
[Op.and]: [{ to_id: to_id }, { to_type: to_type }]
}
]
}
]
}
Hope it helps!

how to implement sub select with where condition in sequelize

I have these tables:
products
stores
produuctProperties
with this structure
[
"products" :
{
"id": 1,
"orginalName": "146153-0100 ",
"title": null,
"stores": [
{
"id": 1,
"stock": 100,
"minOQ": 1,
"maxOQ": 0
},
{
"id": 2,
"stock": 100,
"minOQ": 1,
"maxOQ": 0,
}
],
"productproperties": [
{
"id": 1,
"productId": 1,
"propertyId": 8,
"propertyOptionId": 5
},
{
"id": 2,
"productId": 1,
"propertyId": 9,
"propertyOptionId": 11
},
{
"id": 3,
"productId": 1,
"propertyId": 10,
"propertyOptionId": 9
}
]
}
]
I want filter my products by selected options , Suppose the selected options are 11 and 9
how to implement below sql query in Sequelize 5.6 with findAll , where and... :
select * from products as p
inner join stores as sr on sr.productId = p.id
where (select count(*) from productProperties where propertyOptionId in (11,9) and productId = p.id) >= 2
I've found that using query builder in sequelize is really confusing,
so if you're good with raw sql you could just run them on as below
if Student is you're model
then
const students = Student.query('Select * from students');