Sequelize 将一个表的两列连接到另一个表的同一列

时间:2021-03-18 00:16:13

标签: mysql node.js sequelize.js

我有一个表 Relation,其中包含 userId1userId2 列,它基本上存储了两个用户之间的关系,userId1 > 和 userId2 是此处从 User 表 id (PK) 列引用的外键。

   id: {
        type: DataTypes.INTEGER.UNSIGNED,
        autoIncrement: true,
        primaryKey: true,
        allowNull: false,
    },
    userId1: {
        type: DataTypes.INTEGER.UNSIGNED,
        allowNull: false,
    },
    userId2: {
        type: DataTypes.INTEGER.UNSIGNED,
        allowNull: false,
    },
    status: {
        type: DataTypes.ENUM,
    },

然后是另一个表帖子,其中包含有关帖子的信息。

          id: {
                type: DataTypes.INTEGER.UNSIGNED,
                autoIncrement: true,
                primaryKey: true,
                allowNull: false,
          },
          content: {
                type: DataTypes.TEXT,
                allowNull: false,
          },
          postedBy: {
                type: DataTypes.INTEGER.UNSIGNED,
                allowNull: false,
          },

我只想获得那些与我有关系的用户的帖子列表,比如朋友,这意味着我的 id 假设是 1 并且它在 userId1 列和 userId2 列中有 id,然后我想从 posts 2 的帖子>postedBy 列。 这种情况反之亦然,因为我的 id 可以在 userId2 列中,我需要获取其值在 userId1 列中的用户的所有帖子。

我已经通读了所有问题和答案,例如多重关联,但它对我不起作用。

这是我在帖子模型中的关联

      Posts.hasOne(RelationModel, {
        foreignKey: 'userId1',
        sourceKey: 'postedBy',
        as: 'first',
      })

       Posts.hasOne(RelationModel, {
            foreignKey: 'userId2',
            sourceKey: 'postedBy',
            as: 'second',
        })

下面是我的包含数组。

          include:[
                   {
                    model: RelationModel,
                    as: 'first',
                    where: {
                        status: 'accepted',
                        [Op.or]: [
                            { userId1: request.user.id },
                            { userId2: request.user.id },
                        ],
                    },
                },
                {
                    model: RelationModel,
                    as: 'second',
                    where: {
                        status: 'accepted',
                        [Op.or]: [
                            { userId1: request.user.id },
                            { userId2: request.user.id },
                        ],
                    },
                }
               ]

由此生成的查询如下,其中 151 是登录的用户 ID,表示我的 ID

SELECT 
    `posts`.*,
    `first`.*,
    `second`.*
FROM
    `posts` AS `posts`
        INNER JOIN
    `relations` AS `first` ON `posts`.`postedBy` = `first`.`userId1`
        AND (`first`.`userId1` = 151
        OR `first`.`userId2` = 151)
        AND `first`.`status` = 'accepted'
        INNER JOIN
    `relations` AS `second` ON `posts`.`postedBy` = `second`.`userId2`
        AND (`second`.`userId1` = 151
        OR `second`.`userId2` = 151)
        AND `second`.`status` = 'accepted'
WHERE
    `posts`.`deletedAt` IS NULL
ORDER BY `posts`.`id` ASC , `posts`.`id` ASC;

但是我要构建的查询在下面

SELECT 
    `posts`.*,
    `first`.*
FROM
    `posts` AS `posts`
        INNER JOIN
    `relations` AS `first` ON (`posts`.`postedBy` = `first`.`userId2`
        OR `posts`.`postedBy` = `first`.`userId1`)
        AND (`first`.`userId1` = 151
        OR `first`.`userId2` = 151)
        AND `first`.`isFriend` = TRUE
        AND `first`.`status` = 'accepted'
WHERE
    `posts`.`deletedAt` IS NULL
ORDER BY `posts`.`id` ASC , `posts`.`id` ASC;

如何在 sequelize 中构造这个查询?

1 个答案:

答案 0 :(得分:0)

您需要为关联中的每个关系以及查询的 as 指定唯一的 include 关键字。

Posts.hasOne(RelationModel, {
  foreignKey: 'userId1',
  sourceKey: 'postedBy',
  as: 'first',
});

Posts.hasOne(RelationModel, {
  foreignKey: 'userId2',
  sourceKey: 'postedBy',
  as: 'second',
});

然后在查询时指定唯一的 as 来标识连接的关系

Post.findByPk(id, {
  include: [{
    model: RelationModel,
    as: 'first',
  },
  {
    model: RelationModel,
    as: 'second',
  }],
});