首页 > 解决方案 > Sequelize MySQL - 加入来自同一个关联表的两行

问题描述

我遇到了一个涉及 Sequelize MySQL 的棘手问题。我有两个模型:CalibrationDevice,分别关联多对一。

const Calibration = sequelize.define('Calibration', {
        id: {
            type: DataTypes.UUID,
            primaryKey: true,
            defaultValue: DataTypes.UUIDV4
        },
        date: {
            type: DataTypes.DATEONLY,
            allowNull: false
        },
        document: DataTypes.STRING,
        status: DataTypes.STRING
    });

    Calibration.associate = (models) => {
        models.Calibration.belongsTo(models.Device, {
            foreignKey: 'deviceId',
            onDelete: 'CASCADE'
        });
    };


const Device = sequelize.define('Device', {
        id: {
            type: DataTypes.STRING,
            primaryKey: true,
            defaultValue: DataTypes.UUIDV4
        },
        name: DataTypes.STRING,
        description: DataTypes.STRING,
        serialNo: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        },
        calibrationPeriod: DataTypes.INTEGER,
        location: DataTypes.STRING,
        seller: DataTypes.STRING,
        servicePartner: DataTypes.STRING,
        deviceFunction: DataTypes.STRING,
        quantity: DataTypes.INTEGER,
        status: DataTypes.STRING,
        comment: DataTypes.STRING
    });

现在的重点是,我想查询一个列表DeviceCalibration每个设备项都有两个日期属性,引用两个相关的校准,一个是最近的日期,另一个是最近的未来日期。这非常棘手,我还没有找到解决方案。非常感谢您的帮助。

更新:这是我目前正在做的事情,事实上,我对此还不满意,因为我更喜欢另一种将它们全部组合在 1 个查询中的方式,而不是像这样的 3 个:

let result = await Device.findAll({
                    include: [{ model: Category, attributes: ['id', 'name'] }],
                    order: [['createdAt', 'DESC']], raw: true
                });
await Promise.map(result, async (item, i) => {
    const lastCalibration = await Calibration.findAll({
                        attributes: ['id', 'date'],
                        where: { date: { [Op.lte]: Sequelize.fn('curdate') }, deviceId: item.id },
                        include: [{ model: Device, attributes: ['id'] }],
                        order: [['date', 'DESC']],
                        limit: 1,
                        raw: true
                    });
    const nextCalibration = await Calibration.findAll({
                        attributes: ['id', 'date'],
                        where: { date: { [Op.gt]: Sequelize.fn('curdate') }, deviceId: item.id },
                        include: [{ model: Device, attributes: ['id'] }],
                        order: [['date', 'ASC']],
                        limit: 1,
                        raw: true
                    });
result[i] = { ...item, lastCalibration: lastCalibration[0], nextCalibration: nextCalibration[0] };

标签: javascriptmysqlnode.jssequelize.js

解决方案


我认为关联可以通过以下方式实现:

include: [Calibration], 
through: { 
    where: {
      [Op.or]: [
      { date1: '10-12-2020' },
      { date2: '11-12-2020' }
    ]
   }
 },

推荐阅读