Sequelize - 在 where 条件下关联表列值

Posted

技术标签:

【中文标题】Sequelize - 在 where 条件下关联表列值【英文标题】:Sequelize - Associate table column value in where condition 【发布时间】:2017-08-18 07:49:15 【问题描述】:

Sequelize - 在 where 条件下关联表列

我想在 sequelize 模型中执行这个查询:

SELECT * FROM `model_game` AS `Game` INNER JOIN `model_activity` AS `Activity` ON `Game`.`ActivityId` = `Activity`.`id`  WHERE `Game`.`startAt` > ('2017-03-25 07:37:36'-`Activity.duration`) AND `Game`.`status` = 'NotStarted';

我尝试使用 sequelize.col() 函数,但仍然无法填充该值。我的代码如下

My Game model . table name model_game

var Game = sequelize.define("Game", 
    startAt: DataTypes.DATE,
    status: DataTypes.ENUM('NotStarted','Completed')
  , 
classMethods: 
      associate: function(models) 
        Activity.belongsTo(models.Activity);
      

);

我的Activity模型,表名model_activity

var Activity = sequelize.define("Activity", 
    title: DataTypes.STRING,
    duration: DataTypes.INTEGER
  ,
classMethods: 
      associate: function(models) 
        Activity.hasMany(models.Game);
      

);

查找查询,现在返回值但 sequelize.col("Activity.duration") 完全没有效果

var currentTime = moment();
models.Game.findAndCountAll(
            where:  status: 'NotStarted',   
            startAt: gt: currentTime.subtract(moment.duration(sequelize.col("Activity.duration"), 'minutes')), 
            ,
            include: [
                model: models.Activity             
            ]
        ).then(function(result) 
     //Success
);

但是上面的代码没有填充“Activity.duration”的持续时间值。并且没有错误,应该采取什么措施来纠正这个问题。提前致谢

【问题讨论】:

【参考方案1】:

您可以尝试将DATE_SUB() 函数与sequelize.literal 结合使用。

models.Game.findAndCountAll(
    where: 
        status: 'NotStarted',
        startAt: 
            $gt: models.sequelize.fn(
                'DATE_SUB',
                models.sequelize.literal('NOW()'),
                models.sequelize.literal('INTERVAL Activity.duration MINUTE')
            )
        
    ,
    include: [models.Activity]
).then(result => 
    // result...
);

上面的代码会生成类似于下面的查询:

SELECT * FROM games INNER JOIN activities
ON games.activityId = activities.id
WHERE games.status = 'NotStarted'
AND games.startAt > DATE_SUB(NOW(), INTERVAL activities.duration MINUTE);

根据您的代码和您要获取的查询,我使用NOW() 作为您要减去Activity.duration 字段的日期。此外,我使用了MINUTE 间隔,但您可以根据Activity.duration 字段表示的内容(小时、分钟、秒等)来更改它。

【讨论】:

感谢您的回答。但我收到了这个错误。错误:ER_BAD_FIELD_ERROR:“where 子句”中的未知列“Activity.duration” 尝试INTERVAL "Activity"."duration" MINUTE,或者,如果没有帮助,请查看正在生成的sql并将Activity替换为活动表的正确别名。 谢谢,在 Activity 模型中添加 required:true 解决了这个问题 :)

以上是关于Sequelize - 在 where 条件下关联表列值的主要内容,如果未能解决你的问题,请参考以下文章

使用 sequelize 将 datetime 转换为 where 条件下的列的日期

egg.js 24.12sequelize模型-where操作符

如何在 sequelize.js 中有条件地加载关联?

在子查询中续集“WHERE”子句

Join 中的 Sequelize 或条件

如何使用包含模型中的属性来创建 where 条件?