【问题标题】:Select from multiple tables in sequelize从sequelize中的多个表中选择
【发布时间】:2020-02-09 04:24:38
【问题描述】:

我正在努力研究如何使用 Sequelize 从两个表中进行选择。

其实我正在努力:

SELECT * FROM users, clients WHERE user.id = clients.user_id

我不知道如何使用我描述的两个表,我做的唯一得到一些结果的事情是:

const clients = await Client.findAll({
    attributes: ["user_id"],
});

const users = [];
for (const client of clients) {
    let user = await User.findAll({
        where: {
            id: {
                [Op.eq]: client.user_id
            }
        }
    });
    users.push(user);
}

这会给我一些回报:

[
    [
        {
            "id": 1,
            "first_name": "Velda",
            "middle_name": "Zboncak",
            "last_name": "Kris",
            "email": "vkris10@hotmail.com",
            "created_at": "2020-02-07T20:09:29.484Z",
            "updated_at": "2020-02-07T20:09:29.484Z"
        }
    ]
];

【问题讨论】:

    标签: sql node.js postgresql sequelize.js


    【解决方案1】:

    模型和关联

    首先,您需要在您的表格模型中创建正确的associations。在这种情况下,对于用户和客户端,它应该是 Client.belongsTo(...)

    看看用户模型:

    const { Model, DataTypes } = require("sequelize");
    class User extends Model {
        static init(sequelize) {
            super.init({
                first_name: DataTypes.STRING,
                middle_name: DataTypes.STRING,
                last_name: DataTypes.STRING,
                email: DataTypes.STRING
            }, { sequelize });
        }
    }
    module.exports = User;
    

    看看Client模型:

    const { Model, DataTypes } = require("sequelize");
    
    class Client extends Model {
        static init(sequelize) {
            super.init({
                user_id: DataTypes.INTEGER // The foreign key
            }, { sequelize });
        }
    
        static associate(models) {
            Client.belongsTo(models.User, {
                foreignKey: "id", // Column name of associated table
                as: "user" // Alias for the table
            });
        }
    }
    module.exports = Client;
    

    在关联表时,您需要记住associate 方法中的那些值,即foreignKey: "id" models.ModelName 中的列名,将用于进行连接, 和 as: "user" 用作表的别名,例如 SELECT t.column1 FROM table AS t;

    控制器

    好的,现在您已经设置了模型,您需要设置控制器,魔法发生的地方。正如您所说,您想使用以下方式获取结果:

    SELECT * FROM users, clients WHERE user.id = clients.user_id
    

    但是要达到相同的结果,您可以按照sql join method 从 db 中获取结果,因此它将是这样的:

    SELECT
        "user"."first_name", "user"."middle_name", "user"."last_name", "user"."email"
    FROM "clients" AS "client"
    LEFT JOIN "users" AS "user"
    ON "client"."id" = "user"."id";
    

    知道我们可以在sequelize中讨论including tables,与associations相同

    const Client = require("./path/to/models/Client");
    module.exports = {
        async fetchAll(req, res) {
            const results = await Client.findAll({
                limit: 25,
                include: [
                    {
                        association: "user",
                        attributes: ["first_name", "middle_name", "last_name", "email"]
                    }
                ]
            });
            return res.json(results);
        },
    };
    

    现在让我们谈谈代码中发生了什么:

    • Model.findAll({}) 将获取指定表内的所有结果,在本例中为clients 表。
    • limit: 25 会将您的结果限制为仅 25 行,您可以根据需要随意删除或编辑。
    • include: [],它将通过您指定的表进行连接,因为您只需要users 表,我们将只使用一个对象,因此assossiation: "user" 将在表之间建立这种连接,您必须使用在模型中设置的相同别名。至少 attributes: ["columns"] 是您设置要获取的所有字段的位置。

    就是这样,您提出请求,结果将与我提到的完全相同。结果将是:

    [
        {
            "id": 1,
            "user_id": 1,
            "user": {
                "first_name": "John",
                "middle_name": "Ironsight",
                "last_name": "Doe",
                "email": "johndoe@example.com"
            }
        }, {...}
    ]
    

    【讨论】:

      【解决方案2】:

      可以在include中使用where。在here找到文档

      let user_id = client.user_id;
      users = await User.findAll({
          include: [
              {
                  model: Client,
                  as: 'client',
                  where: {
                      user_id: user_id
                  }
              }
          ]
      });
      

      【讨论】:

      • 考虑到你每次都需要一个新的client.user_id for 循环,它会在一个非常特殊的情况下工作。我认为一个 sql JOIN 方法会给他他需要的结果。
      猜你喜欢
      • 2017-07-20
      • 2018-03-30
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 2021-12-23
      • 1970-01-01
      • 2011-02-16
      相关资源
      最近更新 更多