简体   繁体   中英

Sequelize join two columns of one table to the same column of another table

I have a table Relation with columns userId1 and userId2 it basically stores the relation between two users, userId1 and userId2 is foreign key here referenced from the User tables id (PK) column.

   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,
    },

Then there is another table Posts containing information about posts.

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

I want to get lists of post of only those user who have a relation with me like friends , means my id lets suppose is 1 and it is in userId1 column and userId2 column has id in it, then I want to fetch all posts of value 2 from posts postedBy column. This case can be vice versa as my id can be in userId2 column and I need to get all posts of the user whose value is in userId1 column.

I have read through all the questions and answers like multiple associations but it is just not working for me.

This is my associations in Posts model

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

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

Below is my include array.

          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 },
                        ],
                    },
                }
               ]

The query being generated from this is below, where 151 is the logged in user id, means my 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;

But the query I want to build is below

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;

How to construct this query in sequelize?

You need to specify a unique as keyword for each relationship in the association as well as on the include for your query.

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

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

Then when you query you specify the unique as that identifies the relationship for the join

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM