Sequelize - 子选择关联以过滤父模型

Posted

技术标签:

【中文标题】Sequelize - 子选择关联以过滤父模型【英文标题】:Sequelize - Subselect association to filter parent model 【发布时间】:2022-01-05 09:43:32 【问题描述】:

我最近开始使用Sequelize 6。当前尝试表达以下查询失败。

SELECT u.*
FROM users u
JOIN requests r
ON u.id = r.user_id
WHERE (r.status = true AND r.created_at IN (SELECT 
 MAX(r.created_at)
 FROM users u
 INNER JOIN requests r ON r.user_id = u.id
 GROUP BY u.id))
GROUP BY u.id, r.id

到目前为止我所尝试的:

const result = await User.findAll(
  offset: page,
  subQuery: false,
  limit: rowsPerPage,
  where: 
    '$requests.status$': true,
  ,
  include: [
    as: 'requests',
    model: Request,
    separate: true,
    required: true,
    order: [['createdAt', 'desc']],
    limit: 1,  // problem is here -> error: missing FROM-clause entry for table "requests"
  ],
);

换句话说,我试图在关联的status 值在最后一条记录上为真时加载父模型,并返回每个单独的用户与其最新的协会并排。

关于我评论的限制问题,这个帖子可能有用

https://github.com/sequelize/sequelize/issues/11617

【问题讨论】:

看起来您的原始查询与您在 Sequelize 中尝试执行的操作不太匹配。你能仔细检查你的原始查询吗?在您的数据库上尝试一下,看看您是否得到了您期望的结果。对我来说,查询看起来只返回 1 条仅包含用户数据的记录。 (带有单个 created_at 时间戳 + 选择的内部连接只有 u.*) @Emma 你是绝对正确的。我今天正在研究它,我遇到了你描述的情况。我已经更新了我的查询:) 【参考方案1】:

我不得不稍微更改原始 SQL 以使用 Sequelize,因为 requiredwhere 的某种组合不能很好地工作。

所以,我偏离了你的描述。

我试图仅在关联的状态时加载父模型 最后一条记录的值为真

如果我理解正确的话,我认为您可以使用having 查询来实现这一点。

const result = await User.findAll(
    offset: page,
    subQuery: false,
    limit: rowsPerPage,
    include: [
        as: 'requests',
        model: Request,
        required: true
    ],
    having:  
        '$requests.createdAt$': [sequelize.fn('MAX', sequelize.col('`requests`.`createdAt`'))],
        '$requests.status$': true
    ,
    group: ['users.id'],
);

这将产生以下 SQL。请尝试此 SQL 并让我知道这是否是您要查找的内容。

SELECT ... FROM `users` AS `users` 
INNER JOIN `requests` AS `requests` 
ON `users`.`id` = `requests`.`userId` 
GROUP BY `users`.`id` 
HAVING `requests`.`createdAt` IN (MAX(`requests`.`createdAt`)) AND `requests`.`status` = 1 
LIMIT 0, 5;

【讨论】:

以上是关于Sequelize - 子选择关联以过滤父模型的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询对关联模型的列求和会为所有父项返回相同的数量

sequelize 是不是可以通过关联表中的属性过滤查询?

将属性名称从关联的子模型拉到父模型

按关联模型排序时,Sequelize 抛出错误“无法找到模型 x 的有效关联”

Sequelize 模型关联不会创建新列

为啥 Sequelize 认为我的模型没有关联?