在自定义字段上使用两个 JOIN 对查询进行 Sequelize

Sequelize query with two JOINs on custom fields

目前我有一个使用以下原始查询的解决方案,效果很好。

这是一个SqlFiddle playground

下面是运行良好的原始查询:

const sql = `SELECT u.*, g.name AS "gender"
  FROM users u
  INNER JOIN connections con ON con.user_id = u.id
  INNER JOIN completed_quizzes q ON q.user_id = u.id
  LEFT JOIN genders g ON g.id = u.gender_id
  WHERE
    con.other_user_id='foo'
    AND q.quiz_id=1
    AND con.status='approved'
    AND u.deleted_at IS NULL
    AND con.deleted_at IS NULL
    AND q.deleted_at IS NULL
  LIMIT 10
  OFFSET 0
`;

但我正在尝试用 Sequelize 的对象建模来替换它。到目前为止,我想出的最有意义的解决方案是:

const sequelize = {
      include: [
        {
          model: ConnectionsModel,
          as: 'connections',
          where: { otherUserId: userId, status: ConnectionStatus.approved },
          required: true,
          duplicating: false
        },
        {
          model: CompletedQuizzesModel,
          as: 'completedQuizzes',
          where: { userId, quizId },
          required: true,
          duplicating: false
        },
        {
          model: GendersModel
        }
      ],
      nest: true,
      // have to specify `raw: false`, otherwise Sequelize returns only the first associated record
      raw: false
    };

它生成以下查询(为了便于阅读,我对其进行了美化):

SELECT u.*, g.name AS gender FROM users AS u 
    INNER JOIN connections AS con ON u.id = con.user_id AND (con.status = 'approved' AND con.other_user_id = 'foo') 
    INNER JOIN completed_quizzes AS q ON u.id = q.user_id AND (q.user_id = 'foo' AND q.quiz_id = '1')
    LEFT OUTER JOIN genders AS g ON u.gender_id = g.id 
WHERE u.deleted_at IS NULL 
LIMIT 20 
OFFSET 0;

但它 returns 什么都没有...没有行。而原始解决方案 returns 根据需要添加行。

我可以看到一般 where(应用于原始查询中的整个查询)和附加到 [=15= 中的 on 子句的相同属性之间的区别]s。不过不确定这是否是问题所在。

又是SqlFiddle playground

您在 include 选项 CompletedQuizzesModel 中添加了一个额外条件。在原始 SQL 查询中,您没有条件 userId.

所以这个include应该是这样的:

{
          model: CompletedQuizzesModel,
          as: 'completedQuizzes',
          where: { quizId }, // removed userId
          required: true,
          duplicating: false
        }

结果查询与原始查询一样:

SELECT u.*, g.name AS gender FROM users AS u 
    INNER JOIN connections AS con ON u.id = con.user_id AND (con.status = 'approved' AND con.other_user_id = 'foo') 
    INNER JOIN completed_quizzes AS q ON u.id = q.user_id AND (q.quiz_id = '1')
    LEFT OUTER JOIN genders AS g ON u.gender_id = g.id 
WHERE u.deleted_at IS NULL 
LIMIT 20 
OFFSET 0;