在我的域模型中,我有以下三种模型:
var challenge = sequelize.define('Challenge', {
challengeId: {
field: 'challenge_id',
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
},
ownerId: {
type: DataTypes.INTEGER,
references: { model: 'USER', key: 'user_id'},
allowNull: false
},
description: {
field: 'description',
type: DataTypes.TEXT,
allowNull: false
}
};
challenge.belongsTo(models.User, {foreignKey: 'ownerId'});
challenge.hasMany(models.Idea, {foreignKey: 'challengeId'});
var idea = sequelize.define('Idea', {
ideaId: {
field: 'idea_id',
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
},
challengeId: {
field: 'challenge_id',
type: DataTypes.INTEGER,
references: { model: 'CHALLENGE', key: 'challenge_id'},
allowNull: true
},
description: {
field: 'description',
type: DataTypes.STRING(600),
allowNull: false
}
};
idea.belongsTo(models.Challenge, {foreignKey: 'challengeId'});
var user = sequelize.define('User', {
userId: {
field: 'user_id',
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
unique: true
},
name: {
field: 'name',
type: DataTypes.STRING,
allowNull: false
}
}
user.hasMany(models.Challenge, {foreignKey: 'ownerId'});
这表示一个简单的域模型,其中挑战由特定用户拥有。一个想法与一个或零个挑战相关联。
现在,我想搜索所有挑战,并添加一个与该挑战相关的想法数量。这个查询是我工作的,但是一旦我也想要包含用户信息,生成的SQL中的连接就不正确了。
要查询挑战并获得一些想法,我会这样做:
models.Challenge.findAll({
attributes: ["Challenge.*", [models.sequelize.fn('COUNT', models.sequelize.col('Ideas.idea_id')), 'IdeaCount']],
include: [{
model: models.Idea,
attributes: []
}],
group: ["Challenge.challenge_id"],
order: [['count', 'ASC']]
}).then(function (rows) {
console.log(rows)
});
执行正确的SQL查询:
SELECT "Challenge"."challenge_id" AS "challengeId",
"Challenge".*,
COUNT("Ideas"."idea_id") AS "IdeaCount"
FROM "CHALLENGE" AS "Challenge"
LEFT OUTER JOIN "IDEA" AS "Ideas"
ON "Challenge"."challenge_id" = "Ideas"."challenge_id"
WHERE "Challenge"."company_id" = 1
GROUP BY "Challenge"."challenge_id"
ORDER BY "createdAt" DESC;
现在,当我想要包含来自挑战创建者的信息时,我得到了错误的SQL。
models.Challenge.findAll({
attributes: ["Challenge.*", [models.sequelize.fn('COUNT', models.sequelize.col('Ideas.idea_id')), 'IdeaCount']],
include: [{
model: models.Idea,
attributes: []
},
{
model: models.User,
attributes: ["userId", "name"]
}],
group: ["Challenge.challenge_id"],
order: [['count', 'ASC']]
}).then(function (rows) {
console.log(rows)
});
这导致以下SQL:
SELECT "Challenge".*,
COUNT("Ideas"."idea_id") AS "IdeaCount",
"User".*
FROM "CHALLENGE" AS "Challenge"
LEFT OUTER JOIN "IDEA" AS "Ideas"
ON "Challenge"."challenge_id" = "Ideas"."challenge_id"
INNER JOIN "USER" AS "User"
ON "Challenge"."ownerId" = "User"."user_id"
LEFT OUTER JOIN ("USER_ROLE" AS "User.Roles.USER_ROLE"
INNER JOIN "ROLE" AS "User.Roles"
ON "User.Roles"."role_id" =
"User.Roles.USER_ROLE"."feature_id")
ON "User"."user_id" = "User.Roles.USER_ROLE"."user_id"
WHERE "Challenge"."company_id" = 1
GROUP BY "Challenge"."challenge_id"
LIMIT 20;
相反,我需要这样的SQL查询:
SELECT "Challenge".*,
"User"."user_id",
"User"."firstname",
"User"."lastname"
FROM (SELECT "Challenge".*,
COUNT("Ideas"."idea_id") AS "IdeaCount"
FROM "CHALLENGE" AS "Challenge"
LEFT OUTER JOIN "IDEA" AS "Ideas"
ON "Challenge"."challenge_id" =
"Ideas"."challenge_id"
WHERE "Challenge"."company_id" = 1
GROUP BY "Challenge"."challenge_id") AS "Challenge"
LEFT OUTER JOIN "USER" AS "User"
ON "User"."user_id" = "Challenge"."ownerId"
ORDER BY "createdAt" DESC
LIMIT 20;
似乎sequelize将用户的左外连接放在与用于计算关联的级别相同的级别上。相反,用户信息的连接应该在它之外发生。是否有可能以这样的方式影响sequelize,就像在上面描述的SQL语句中那样单独完成此连接?