Sequelize left join和inner join分别在什么情况出现
发布于 6 年前 作者 lyt308012546 9634 次浏览 来自 问答

前提

不能更改数据库表,只能更改代码

问题

left join和inner join分别在什么情况出现, 分别如何设置associate 以下代码为什么是inner join,如何设置associate才能变成left join

以下代码业务逻辑

活动可以有卡券,也可以没有卡券,现在查询所有活动,并关联卡券表,获取卡券信息

创建表SQL

CREATE TABLE rel_event_card (
	id INT AUTO_INCREMENT PRIMARY KEY,
	event_id INT(11) DEFAULT '0' NOT NULL COMMENT '活动ID',
	card_id INT(11) DEFAULT '0' NOT NULL COMMENT '卡券ID'
) COMMENT '活动卡券关系表' ENGINE = INNODB;

CREATE TABLE  x_event (
	id INT AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(255) DEFAULT '' NOT NULL COMMENT '活动名称',
) COMMENT '活动表' ENGINE = INNODB;

活动表model

module.exports = app => {
    const DataTypes = app.Sequelize;
    // 活动表
    const Model = app.model.define('xEvent', {
        // 唯一主键
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true,
            field: 'id'
        },
        // 活动名称
        name: {
            type: DataTypes.STRING(255),
            allowNull: false,
            defaultValue: '',
            field: 'name'
        }
    }, {
        tableName: 'x_event',
        timestamps: false
    });
    Model.associate = function() {
        Model.hasOne(app.model.RelEventCard, { foreignKey: 'eventId' });
    };
    return Model;
};

活动卡券关系表model

module.exports = app => {
    const DataTypes = app.Sequelize;
    // 活动卡券关系表
    const Model = app.model.define('relEventCard', {
        // 
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true,
            field: 'id'
        },
        // 活动ID
        eventId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            defaultValue: '0',
            field: 'event_id'
        },
        // 卡券ID
        cardId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            defaultValue: '0',
            field: 'card_id'
        }
    }, {
        tableName: 'rel_event_card',
        timestamps: false
    });

    Model.associate = function() {
        Model.belongsTo(app.model.XEvent, { foreignKey: 'eventId'});
    };
    return Model;
};

sequelize查询代码

   let eventRecs = await XEvent.findAll({
                where: {
                    status: 1,
                    id: id
                },
                include: [
                    {
                        model: RelEventCard,
                        where: {
                            status: 1
                        }
                    }
                ]
            });

sequelize 执行sql

SELECT
	`xEvent`.`id`,
	`xEvent`.`name`,
	`relEventCards`.`id` AS `relEventCards.id`,
	`relEventCards`.`event_id` AS `relEventCards.eventId`
FROM
	`x_event` AS `xEvent`
	INNER JOIN `rel_event_card` AS `relEventCards` ON `xEvent`.`id` = `relEventCards`.`event_id` 
	AND `relEventCards`.`STATUS` = 1
WHERE
	`xEvent`.`status` = 1 
	AND `xEvent`.`id` = '12';
1 回复
  • 如果include 中的include.require=true (默认是应该false ?) 的时候会变为inner join.
  • 如果include 中有include.where条件,会隐式的将include.require设置为true,然后这里得到的就是inner join. (你这个例子应该就是这种情况) 有段时间没用了,你自己参考下文档 docs.sequelizejs

如果主表中的数据比较少,可以试试 加一个include.separate = true (这里应该是会跑两个SQL select * from xEvent where status = 1 and id = '12' , 另外 select * from relEventCards where event_id in [...] and status =1 ) 或者直接自己写sql用 sequelize.query 去做吧

回到顶部