【问题标题】:Sequelize MySQL - Join with two rows from same associated tableSequelize MySQL - 加入来自同一个关联表的两行
【发布时间】:2020-03-22 14:14:24
【问题描述】:

我遇到了一个涉及 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
    });

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

更新:这是我目前正在做的事情,事实上,我对此还不满意,因为我更喜欢另一种仅在 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] };

【问题讨论】:

  • 您能分享一下您想使用 Sequelize 生成的 SQL 吗?
  • 在hibernate中,这种关联可以通过连接表来实现,以获得灵活性和可扩展性。所以你会看看如何在 Sequelize 中实现连接表。
  • @SohamLawar 好吧,关键是我自己现在想不出这样的查询
  • @tksilicon 你能帮我举个例子吗?谢谢

标签: javascript mysql node.js sequelize.js


【解决方案1】:

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

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

【讨论】:

  • 看一下查询,我的朋友,我怀疑您是否正确理解了我需要的查询:(
  • 据我了解,您的设备有两个相关的校准日期。因此,当您加入表时,将使用并在 op.or 中检查 date1 和 date2 上定义的两个外键。与您分享 Sequelize 查询。
  • 据我了解您的查询,这类似于在这两天之间选择一个 calib@ration。但其实是另外一回事,我会更新我的问题
猜你喜欢
  • 2014-02-06
  • 2021-03-05
  • 2018-10-04
  • 2016-04-05
  • 2016-01-24
  • 2019-04-14
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
相关资源
最近更新 更多