【问题标题】:Is it possible to do a subquery with Sequelize.js?是否可以使用 Sequelize.js 进行子查询?
【发布时间】:2015-01-25 06:50:12
【问题描述】:

我的查询看起来像:

select es.EssayId, (esmax.WordCount - esmin.WordCount)
from (select es.EssayId, min(es.EssayDate) as mined, max(es.EssayDate) as maxed
      from EssayStats es
      group by es.EssayId
     ) es join
     EssayStats esmin
     on es.EssayId = esmin.EssayId and es.mined = esmin.EssayDate join
     EssayStats esmax
     on es.EssayId = esmax.EssayId and es.maxed = esmax.EssayDate;

是否可以用 Sequelize.js ORM 编写这个?我知道我可以直接使用query,但我想知道是否可以构造。

【问题讨论】:

  • 我不这么认为。急切的加载可能是最接近的事情。 Here's an example where Sequelize generates a sub-query via eager loading, because of an artificial limit.
  • 我对@9​​87654325@一无所知。是否可以使用其 ORM 编写类似EssayStats t1 LEFT JOIN EssayStats t2 ON t1.EssayId = t2.EssayId AND t1.EssayDate < t2.EssayDate 的内容?如果答案是YES,那么您可以编写不带子查询和不带GROUP BY 的查询。但是,您需要将表连接到自身 3 次,一次使用 INNER JOIN,两次使用 LEFT JOIN

标签: mysql sequelize.js


【解决方案1】:

我认为您的问题不可能得到明确的答案。见#1869

不幸的是,目前无法查询直通模型/连接表。

为了回答标题问题,Sequelize 会自动生成一个子查询(例如,#1719),但您不能执行自定义子查询。我没有权威的否定参考。


看起来你的桌子是这样的:

EssayStats
    EssayId
    EssayDate
    WordCount

然后你可以这样做:

return EssayStat.findAll({
    attributes: [
        [sequelize.literal('((SELECT wordCount FROM "EssayStats" WHERE "EssayId" = "EssayStat"."EssayId" EssayStat BY "createdAt" DESC LIMIT 1) - (SELECT wordCount FROM "EssayStats" WHERE "EssayId" = "EssayStat"."EssayId" EssayStat BY "createdAt" ASC LIMIT 1))'), 'difference'],
        'EssayId'
    ],
    group: ['EssayId']
});

它所做的只是运行两个 SELECT 查询,在按您感兴趣的变量排序后从这些查询中获取 MAX 和 MIN,然后获取您的差异。这将为您提供您感兴趣的内容:最新版本和第一个版本之间的字数差异。

这里的诀窍是在属性字段中封装一个 SELECT 语句。

当然,它很乱,可能并不比罐头sequelize.query 好多少。但它确实回答了你问题的要点。

更好的解决方案可能是对您的数据进行一些非规范化处理,并将“wordCountDelta”直接存储在您的 Essay 模型中。然后你可以有一个afterCreate hook 来自动更新该字段。这很可能也是最快的解决方案。

我回答了类似的here

【讨论】:

    【解决方案2】:

    子查询示例

    ModelA.findAll({
        where: {
            $or: [
                {'$B.someColumn$' : someCondition},
                {'$C.someOtherColumn$' : someOtherCondition}
            ]
        },
        include: [{
            model: ModelB,
            required: false,  //true or false for required 
            where:{id:$id}
    
        }, {
            model: ModelC,
            required: false, //true or false for required 
            where:{id:$id}
        }]
    }); 
    

    希望有用:D

    【讨论】:

    • 嗨@Derit,在这里我想要模型A 的别名,模型B 加入输出,然后再次将该输出与模型C 连接。有什么办法吗?例如:select uid,col1,col2,col3 from( select A.id as uid,col1,col2,col3 from A inner join B in A.id = B.mid where somecondition ) as 't' inner join users as u on t.uid = u.id
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 2011-02-10
    • 2023-03-23
    • 2014-06-09
    • 1970-01-01
    相关资源
    最近更新 更多