【问题标题】:Sequelize WHERE NOT EXISTS()Sequelize WHERE NOT EXISTS()
【发布时间】:2021-09-18 15:53:39
【问题描述】:

我有一个多对多的关系,如下所示:

var Genres = db.define('Movie', {
    name: {
        type: Sequelize.STRING(100),
        allowNull: false
    },
    description: {
        type:Sequelize.STRING(),
        allowNull: true
    },
    thumbnail: {
        type: Sequelize.BLOB(),
        allowNull: true
    },
    urlposter: {
        type: Sequelize.STRING(245),
        allowNull: true
    }
});
var Users = db.define('User', {
    username: {
        type: Sequelize.STRING(25),
        allowNull: false
    },
    password: {
        type: Sequelize.STRING(25),
        allowNull: false
    }
});
Movies.belongsToMany(Users, {through: UM, foreignKey: 'Id_Movies'});
Users.belongsToMany(Movies, {through: UM, foreignKey: 'Id_Users'});

我要做的是返回所有没有链接到特定用户的电影

这是我想要实现的 SQL 查询:

SELECT m.* 
FROM Movies m 
WHERE NOT EXISTS(SELECT NULL 
FROM Users_Movies sc 
WHERE sc.Id_Movies = m.id AND sc.Id_Users = 1)

这是我所拥有的最接近的,但这只会返回所有链接 u 用户 ID 为 1 的电影

            Movies.findAll({
            include: [
            // {
            //  model:Genres,
            //  through:{attributes:[]}
            // },
            {
                model:Users,
                through:{attributes:[]},
                where: {id: 1},
                required: true,
            }],
        })
        .then(function(movies){
            done(null, movies);
        })
        .catch(function(error){
            done(error, null);
        });

但我想反转它。

现在我唯一的选择是进行 2 个查询,一个包含所有电影,一个包含所有具有链接的电影并循环遍历列表并将它们从第一个列表中删除。这不是漂亮的代码。

【问题讨论】:

  • 你说你想得到所有电影没有链接到特定用户,但你说你想实现的 SQL 有AND sc.Id_Users = 1。这是否与特定用户无关?
  • 不,不是……如果您运行它,它将返回所有与 id 为 1 的用户无关的电影
  • 从包含的 Users 模型中删除 required: true 并将 where: {'Users.id': null} 添加到查询中。我不确定确切的字段命名,但我想你已经明白了。

标签: javascript sql node.js sequelize.js


【解决方案1】:

我知道我迟到了,但我认为在查询的“where”中使用文字“users.id IS NULL”可以解决问题:

 Movie.findAll({
    where: sequelize.literal("users.id IS NULL"),
    include: [
      {
        model: Users,
        through: { attributes: [] }
      }],
  })
    .then(function (movies) {
      done(null, movies);
    })
    .catch(function (error) {
      done(error, null);   
    });

此解决方案基于以下 Github 问题:https://github.com/sequelize/sequelize/issues/4099

【讨论】:

    【解决方案2】:

    使用 rawQuery

    const projects = await sequelize.query('SELECT * FROM projects', {
      model: Projects,
      mapToModel: true // pass true here if you have any mapped fields
    });
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2015-10-02
    • 2013-04-17
    • 1970-01-01
    • 2018-11-11
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 2016-05-19
    相关资源
    最近更新 更多