如何在Nodejs中使用Sequelize在没有公共列的两个表上进行INNER JOIN?

Posted

技术标签:

【中文标题】如何在Nodejs中使用Sequelize在没有公共列的两个表上进行INNER JOIN?【英文标题】:How to do INNER JOIN on two tables without common columns using Sequelize in Nodejs? 【发布时间】:2021-04-05 03:33:45 【问题描述】:

我有两张桌子。

广告系列

id cause GoalType Target
1 5 0 5000
2 4 1 34500
3 5 1 50000
4 1 0 9000
5 8 1 35000
6 3 1 60000

模型定义为:

module.exports = (sequelize, Sequelize) => 
    const Campaigns = sequelize.define('Campaigns', 
        id:  type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true ,
        cause: Sequelize.INTEGER,
        goalType: Sequelize.INTEGER,
        target: Sequelize.FLOAT,
    , 
        freezeTableName: true,
    );
    return Campaigns



Campaign_Tasks

id uuid action Status userId
1 001-0000004 2 0 50
2 001-0000004 1 4 60
3 001-0000003 2 7 50
4 001-0000007 0 10 40
5 001-0000010 1 3 30
6 001-0000003 0 5 50

模型定义为:

module.exports = (sequelize, Sequelize) => 
    const Campaign_Tasks = sequelize.define('Campaign_Tasks', 
        id:  type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true ,
        userId: Sequelize.INTEGER,
        uuid: Sequelize.STRING,
        action: Sequelize.INTEGER,
        status: Sequelize.INTEGER,
    , 
        freezeTableName: true,
    );
    return Campaign_Tasks

tasks表中的每个UUID都对应campaign表中的id(每个UUID都是从id间接生成的,这个过程是可逆的)。但可以看出,两个表中都没有公共列。 我需要根据活动表中的 id 和活动表中的 uuid 找到这两个表的内连接(其中 uuid 不是活动表的 PK)

按照本教程:https://lorenstewart.me/2016/09/12/sequelize-table-associations-joins/ 我创建了一个数据库对象。这是必要的,因为我无法在任何一个模型文件中定义关联,因为我不断收到这里提到的错误:hasMany called with something that's not an instance of Sequelize.Model

const db = require('./models/index')

const db_ = ;

db_.Sequelize = db.Sequelize;
db_.sequelize = db.sequelize;

//Models/tables
db_.campaigns = require('./models/campaigns')(db.sequelize, db.Sequelize);
db_.campaign_Tasks = require('./models/campaignTasks')(db.sequelize, db.Sequelize);

//Relations
db_.campaign_Tasks.belongsTo(db_.campaigns);
db_.campaigns.hasMany(db_.campaign_Tasks);

module.exports = db_;

如何对这两个表进行内部联接。我正在寻找这样的东西:

const uuidToId = require('../../helpers/uuidToId')

let rows = await db_.campaign_Tasks.findAll(
        include: [
            model: db_.campaigns,
            required: true,
            where: 
                id: uuidToId.uuidToId(/*<-uuid from campaign_Tasks rows->*/)
            
        ]
    )

uuidToId 将 UUID 转换回 id。提前致谢。

【问题讨论】:

【参考方案1】:

我想到了三个解决方案:

    运行两个单独的查询,首先获取所有广告系列 ID,生成适当的 uuid,在第二个查询中使用它,然后将结果合并到代码中(我的首选方式); 在您的数据库中创建一个视图,该视图将包含已处理的结果并针对该视图进行选择(请注意,如果您使用计算列,您将无法索引它们,因为 mysql 目前不支持该功能); 使用一种称为交叉连接的方法。它本身不是连接,但它会计算两个表的笛卡尔积。 https://www.mysqltutorial.org/mysql-cross-join/

我从未使用过交叉连接,因为我尽量让查询保持简单,因为它允许我缓存中间结果。

【讨论】:

以上是关于如何在Nodejs中使用Sequelize在没有公共列的两个表上进行INNER JOIN?的主要内容,如果未能解决你的问题,请参考以下文章

使用sequelize POST方法在nodejs中插入新记录

Nodejs / PostgreSQL sequelize - 如何更新/更改数据库中的模型?

如何在 NodeJS Sequelize 中按查询计算组

如何使用nodejs sequelize执行此SQL查询?

在nodejs sequelize中循环获取异步数据

何时在 MYSQL 中使用 Sequelize?