Sequelize ORM中连接表的条件

Posted

技术标签:

【中文标题】Sequelize ORM中连接表的条件【英文标题】:Where condition for joined table in Sequelize ORM 【发布时间】:2016-07-15 17:54:19 【问题描述】:

我想用 sequelize ORM 得到这样的查询:

SELECT "A".*,      
FROM "A" 
LEFT OUTER JOIN "B" ON "A"."bId" = "B"."id"
LEFT OUTER JOIN "C" ON "A"."cId" = "C"."id"
WHERE ("B"."userId" = '100'
       OR "C"."userId" = '100')

问题是续集不允许我在 where 子句中引用“B”或“C”表。以下代码

A.findAll(
    include: [
        model: B,
        where: 
            userId: 100
        ,
        required: false

    , 
        model: C,
        where: 
            userId: 100
        ,
        required: false
    ]
] 

给我

SELECT "A".*,      
FROM "A" 
LEFT OUTER JOIN "B" ON "A"."bId" = "B"."id" AND "B"."userId" = 100
LEFT OUTER JOIN "C" ON "A"."cId" = "C"."id" AND "C"."userId" = 100

这是完全不同的查询,结果是

A.findAll(
    where: 
        $or: [
            '"B"."userId"' : 100,
            '"C"."userId"' : 100
        ]
    ,
    include: [
        model: B,
        required: false

    , 
        model: C,
        required: false
    ]
] 

甚至不是一个有效的查询:

SELECT "A".*,      
FROM "A" 
LEFT OUTER JOIN "B" ON "A"."bId" = "B"."id"
LEFT OUTER JOIN "C" ON "A"."cId" = "C"."id"
WHERE ("A"."B.userId" = '100'
       OR "A"."C.userId" = '100')

sequelize 是否可以进行第一次查询,或者我应该坚持原始查询?

【问题讨论】:

非常有用的问题! 更新(Jan Aagaard Meier)的回答,添加subQuery=false 选项以使用限制和偏移 【参考方案1】:

将引用连接表的列包装在$$

A.findAll(
    where: 
        $or: [
            '$B.userId$' : 100,
            '$C.userId$' : 100
        ]
    ,
    include: [
        model: B,
        required: false

    , 
        model: C,
        required: false
    ]
); 

【讨论】:

如果我添加另一个包含,即required: true,一切都会失败。然后 sequelize 在其中使用 INNER JOIN 进行子查询并将 WHERE 子句放入其中。因此,这会生成无效查询。 SELECT "A".*, FROM (SELECT * FROM "A" INNER JOIN "D" ON "A"."dId" = "D"."id" WHERE ("A"."B.userId" = '100 ' OR "A"."C.userId" = '100') ) 作为 "A" 左外连接 "B" ON "A"."bId" = "B"."id" 左外连接 "C" ON "A"."cId" = "C"."id" 有什么建议可以解决这个问题吗? 这个 $$ 语法是否记录在某处? @xb1itz 运气好可以通过第二次加入解决问题吗?我也遇到了这个问题。 在此处记录:docs.sequelizejs.com/manual/tutorial/… 在“热加载模型的顶层”下 按原样工作,但如果我尝试添加 limit 则会中断。【参考方案2】:

在包含中添加 where 条件以及连接。

    
       model: C,
       where: 
        id: 1
       
   

【讨论】:

如果您想将required: true用作“AND”过滤器,请务必在此处添加required: true

以上是关于Sequelize ORM中连接表的条件的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Sequelize 在 3120 条记录后会暂停?

如何在 Sequelize ORM 中获取不带前缀表名的连接数据结果

使用egg.js和egg-sequelize连接mysql

使用自定义连接表主键 Sequelize BelongsToMany

如何使用 sequelize ORM 编写内连接查询?

Node.js ORM - Sequelize