goods和goodsSkus表
實現 兩表聯表查詢,並分頁。查詢結果中包含兩表中的字段,重點在於子表中返回字段 要寫在include中的attributes中,否則生成的sql無法執行
let queryParams={
name: {
[sequelize.Op.like]: `%$測試%`
}
}
let skuQueryParams = {
name: {
[sequelize.Op.like]: `%$x%`
}
}
daGoodsModel.hasMany(daGoodsSkuModel, {foreignKey: 'goods_id'});
var results = await daGoodsModel.findAll({
order: [['id','asc']],
where: queryParams,
raw: true,
include: [
{
model: daGoodsSkuModel,
attributes:[
[sequelize.col('id'), 'sku_id'],
[sequelize.col('name'), 'sku_name']
],
where: skuQueryParams,
require: true
}
],
attributes: [
'id','name'
],
limit: pageSize,
offset: (pageIndex - 1) * pageSize
});
sku表返回字段放到include.attributes中生成的sql
SELECT `da_goods`.*, `da_goods_skus`.`id` AS `da_goods_skus.sku_id`, `da_goods_skus`.`name` AS `da_goods_skus.sku_name` FROM ( SELECT `da_goods`.`id`, `da_goods`.`name` FROM `da_goods` `da_goods` WHERE ((`da_goods`.`name` LIKE '%測試%' OR `da_goods`.`subtitle` LIKE '%測試%') AND `da_goods`.`deleted` = false AND ( SELECT `goods_id` FROM `da_goods_sku` `da_goods_skus` WHERE `da_goods_skus`.`deleted` = false AND `da_goods_skus`.`name` LIKE '%x%' AND `da_goods_skus`.`goods_id` = `da_goods`.`id` LIMIT 1 ) IS NOT NULL) ORDER BY `da_goods`.`id` ASC LIMIT 0, 10 ) `da_goods` INNER JOIN `da_goods_sku` `da_goods_skus` ON (`da_goods`.`id` = `da_goods_skus`.`goods_id` AND `da_goods_skus`.`deleted` = false AND `da_goods_skus`.`name` LIKE '%x%') ORDER BY `da_goods`.`id` ASC;
sku返回字段放到attributes中
var results = await daGoodsModel.findAll({
order: [['id','asc']],
where: queryParams,
raw: true,
include: [
{
model: daGoodsSkuModel,
attributes:[],
where: skuQueryParams,
require: true
}
],
attributes: [
'id','name',
[sequelize.col('da_goods_skus.id'), 'sku_id'],
[sequelize.col('da_goods_skus.name'), 'sku_name']
],
limit: pageSize,
offset: (pageIndex - 1) * pageSize
});
生成的sql語句,如下語句執行失敗,會報 "Unknown column 'da_goods_skus.id' in 'field list'",因為標紅部分查詢不到
SELECT `da_goods`.* FROM ( SELECT `da_goods`.`id`, `da_goods`.`name`, `da_goods_skus`.`id` AS `sku_id`, `da_goods_skus`.`name` AS `sku_name` FROM `da_goods` `da_goods` WHERE ((`da_goods`.`name` LIKE '%測試%' OR `da_goods`.`subtitle` LIKE '%測試%') AND `da_goods`.`deleted` = false AND ( SELECT `goods_id` FROM `da_goods_sku` `da_goods_skus` WHERE `da_goods_skus`.`deleted` = false AND `da_goods_skus`.`name` LIKE '%x%' AND `da_goods_skus`.`goods_id` = `da_goods`.`id` LIMIT 1 ) IS NOT NULL) ORDER BY `da_goods`.`id` ASC LIMIT 0, 10 ) `da_goods` INNER JOIN `da_goods_sku` `da_goods_skus` ON (`da_goods`.`id` = `da_goods_skus`.`goods_id` AND `da_goods_skus`.`deleted` = false AND `da_goods_skus`.`name` LIKE '%x%') ORDER BY `da_goods`.`id` ASC;
正確返回結果 ,需要對返回字段進行處理,去掉 da_goods_skus
[ { "id": 334, "name": "測試商品", "da_goods_skus.sku_id": 506, "da_goods_skus.sku_name": "xl" }, { "id": 334, "name": "測試商品", "da_goods_skus.sku_id": 507, "da_goods_skus.sku_name": "x" } ]
但是上面node生成sql兩層嵌套,總感覺有問題,並且分頁查詢時如果與goods對應的sku表有多條數據,會返回所有sku,經查是sequelize對sql進行了優化,添加 subQuery:false,即可
代碼
var results = await daGoodsModel.findAll({ order: [['id','asc']], subQuery: false, where: queryParams, include: [ { model: daGoodsSkuModel, attributes:[], where: skuQueryParams } ], attributes: [ 'id','name', [sequelize.col('da_goods_skus.id'), 'sku_id'], [sequelize.col('da_goods_skus.name'), 'sku_name'], ], limit: pageSize, offset: (pageIndex - 1) * pageSize });
生成SQL
SELECT `da_goods`.`id`, `da_goods`.`name`, `da_goods_skus`.`id` AS `sku_id`, `da_goods_skus`.`name` AS `sku_name` FROM `da_goods` `da_goods` INNER JOIN `da_goods_sku` `da_goods_skus` ON `da_goods`.`id` = `da_goods_skus`.`goods_id` AND `da_goods_skus`.`deleted` = false WHERE `da_goods`.`deleted` = false ORDER BY `da_goods`.`id` ASC LIMIT 0, 1;
但是這樣返回的sku永遠只有一條,也就是goods有幾條,返回幾條記錄,對應的sku只返回一條
[{ "id": 334, "name": "測試商品", "sku_id": 506, "sku_name": "xl", }, { "id": 335, "name": "測試1", "sku_id": 508, "sku_name": "aaa", }]
還是有問題
將sku返回字段放到include.attributes 解決問題
var results = await daGoodsModel.findAndCountAll({ order: [['id','asc'],[sequelize.col('da_goods_skus.id'),'asc']], subQuery: false, where: queryParams, include: [ { model: daGoodsSkuModel, attributes:[ [sequelize.col('id'), 'sku_id'], [sequelize.col('name'), 'sku_name'] ], where: skuQueryParams } ], attributes: [ 'id','name' ], limit: pageSize, offset: (pageIndex - 1) * pageSize });
返回結果
[{ "id": 334, "name": "測試商品", "da_goods_skus": [ { "sku_id": 506, "sku_name": "xl" }, { "sku_id": 507, "sku_name": "x" } ], }, { "id": 335, "name": "測試1", "da_goods_skus": [ { "sku_id": 508, "sku_name": "aaa" } ] }]