我想将以下查询转换为续集代码
select * from table_a
inner join table_b
on table_a.column_1 = table_b.column_1
and table_a.column_2 = table_b.column_2
我尝试了很多方法并遵循了许多提供的解决方案,但我无法通过续集代码实现所需的查询。
我实现的最大目标如下:
select * from table_a
inner join table_b
on table_a.column_1 = table_b.column_1
我也想要第二个条件。
and table_a.column_2 = table_b.column_2
任何正确的方法来实现它?
答案 0 :(得分:8)
您需要定义on
语句
JOIN
子句
ModelA.findAll({
include: [
{
model: ModelB,
on: {
col1: sequelize.where(sequelize.col("ModelA.col1"), "=", sequelize.col("ModelB.col1")),
col2: sequelize.where(sequelize.col("ModelA.col2"), "=", sequelize.col("ModelB.col2"))
},
attributes: [] // empty array means that no column from ModelB will be returned
}
]
}).then((modelAInstances) => {
// result...
});
答案 1 :(得分:2)
关于@TophatGordon对接受的答案的怀疑:是否需要在模型中建立任何关联。
还经历了仍处于 open 状态的github issue raised back in 2012。
因此我也处于相同的情况下,尝试为左外部联接设置自己的ON
条件。
当我直接尝试在on: {...}
内使用Table1.findAll(...include Table2 with ON condition...)
时,它不起作用。
它引发了一个错误:
EagerLoadingError [SequelizeEagerLoadingError]: Table2 is not associated to Table1!
我的用例是在左外部联接中将Table1中的两个非主键列与Table2中的两个列进行匹配。我将展示如何以及实现的目标:
不要对表名和列名感到困惑,因为我不得不将它们与我原来使用的表名和列名进行更改。
所以我不得不在Table1(Task)中创建一个关联,例如:
Task.associate = (models) => {
Task.hasOne(models.SubTask, {
foreignKey: 'someId', // <--- one of the column of table2 - SubTask: not a primary key here in my case; can be primary key also
sourceKey: 'someId', // <--- one of the column of table1 - Task: not a primary key here in my case; can be a primary key also
scope: {
[Op.and]: sequelize.where(sequelize.col("Task.some_id_2"),
// '=',
Op.eq, // or you can use '=',
sequelize.col("subTask.some_id_2")),
},
as: 'subTask',
// no constraints should be applied if sequelize will be creating tables and unique keys are not defined,
//as it throws error of unique constraint
constraints: false,
});
};
所以查找查询看起来像这样:
Task.findAll({
where: whereCondition,
// attributes: ['id','name','someId','someId2'],
include: [{
model: SubTask, as: 'subTask', // <-- model name and alias name as defined in association
attributes: [], // if no attributes needed from SubTask - empty array
},
],
});
结果查询:
sequelize.where(...)
中使用的scope:{...}
获得select "Task"."id", "Task"."name", "Task"."some_id" as "someId", "Task"."some_id_2" as "someId2" from "task" as "Task" left outer join "sub_task" as "subTask" on "Task"."some_id" = "subTask"."some_id" and "Task"."some_id_2" = "subTask"."some_id_2";
Task.associate = (models) => {
Task.hasOne(models.SubTask, {
foreignKey: 'someId', // <--- one of the column of table2 - SubTask: not a primary key here in my case; can be primary key also
sourceKey: 'someId', // <--- one of the column of table1 - Task: not a primary key here in my case; can be a primary key also
as: 'subTask',
// <-- removed scope -->
// no constraints should be applied if sequelize will be creating tables and unique keys are not defined,
//as it throws error of unique constraint
constraints: false,
});
};
因此,来自Table0的查找查询如下所示:由于我们现在将使用自定义on: {...}
Table0.findAll({
where: whereCondition,
// attributes: ['id','name','someId','someId2'],
include: {
model: Task, as: 'Table1AliasName', // if association has been defined as alias name
include: [{
model: SubTask, as: 'subTask', // <-- model name and alias name as defined in association
attributes: [], // if no attributes needed from SubTask - empty array
on: {
[Op.and]: [
sequelize.where(
sequelize.col('Table1AliasName_OR_ModelName.some_id'),
Op.eq, // '=',
sequelize.col('Table1AliasName_OR_ModelName->subTask.some_id')
),
sequelize.where(
sequelize.col('Table1AliasName_OR_ModelName.some_id_2'),
Op.eq, // '=',
sequelize.col('Table1AliasName_OR_ModelName->subTask.some_id_2')
),
],
},
}],
}
});
将约束设置为false,就好像sequelize尝试创建第二张表(SubTask)时,由于以下查询,它可能会引发错误(DatabaseError [SequelizeDatabaseError]: there is no unique constraint matching given keys for referenced table "task")
:
如果不存在则创建表“ sub_task”(“ some_id” INTEGER,“ some_id_2” INTEGER在更新时删除级联上引用“任务”(“ some_id”) 级联,“数据”(整数));
如果我们设置 constraint:false ,它会在下面的查询中创建该查询,因为在引用非主列时不会引发唯一约束错误:
如果不存在表,则创建“ sub_task”(“ some_id” INTEGER,“ some_id_2” INTEGER,“ data” INTEGER);