我有一个看起来像的查询:
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
,但我想知道是否可以构建它。
答案 0 :(得分:3)
我认为你的问题不可能得到一个干净的答案。见#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
好多少。但它确实回答了你问题的要点。
更好的解决方案可能是对数据进行非规范化,并直接在“Essay”模型中存储“wordCountDelta”。然后,您可以afterCreate
hook自动更新字段。这很可能也是最快的解决方案。
我回答了类似的问题here。
答案 1 :(得分: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