PostgreSQLデータベースには、契約と支払いの2つのテーブルがあります。 1つの契約で複数の支払いが行われます。
次の2つのモデルがあります。
module.exports = function(sequelize, DataTypes) {
var contracts = sequelize.define('contracts', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true
}
}, {
createdAt: false,
updatedAt: false,
classMethods: {
associate: function(models) {
contracts.hasMany(models.payments, {
foreignKey: 'contract_id'
});
}
}
});
return contracts;
};
module.exports = function(sequelize, DataTypes) {
var payments = sequelize.define('payments', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true
},
contract_id: {
type: DataTypes.INTEGER,
},
payment_amount: DataTypes.INTEGER,
}, {
classMethods: {
associate: function(models) {
payments.belongsTo(models.contracts, {
foreignKey: 'contract_id'
});
}
}
});
return payments;
};
すべての契約に対して行われたすべての支払いを合計し、この関数を使用します。
models.contracts.findAll({
attributes: [
'id'
],
include: [
{
model: models.payments,
attributes: [[models.sequelize.fn('sum', models.sequelize.col('payments.payment_amount')), 'total_cost']]
}
],
group: ['contracts.id']
})
ただし、次のクエリが生成されます。
SELECT "contracts"."id", "payments"."id" AS "payments.id", sum("payments"."payment_amount") AS "payments.total_cost"
FROM "contracts" AS "contracts"
LEFT OUTER JOIN "payments" AS "payments" ON "contracts"."id" = "payments"."contract_id" GROUP BY "contracts"."id";
Payments.idを選択するように要求することはありません。これは、エラーで述べたように、関数ごとに集計またはグループに含める必要があるためです。
おそらく未処理のSequelizeDatabaseError:エラー:列「payments.id」は、GROUP BY句に表示されるか、集計関数で使用される必要があります
私はここで何かが欠けていますか?私は この回答 をフォローしていますが、それでもSQLリクエストが有効になる方法がわかりません。
この問題はSequelize 3.0.1で修正されました。含まれるモデルの主キーは、
attributes: []
集約はメインモデルで行う必要があります( this github issue の情報)。
したがって、私のユースケースでは、コードは次のようになります
models.contracts.findAll({
attributes: ['id', [models.sequelize.fn('sum', models.sequelize.col('payments.payment_amount')), 'total_cost']],
include: [
{
model: models.payments,
attributes: []
}
],
group: ['contracts.id']
})
試して
group: ['contracts.id', 'payments.id']
問題は、payments
から選択してcontracts
に参加するのではなく、逆にしたいですか?
あなたの関数を
models.contracts.findAll({
attributes: [
'models.contracts.id'
],
include: [
{
model: models.payments,
attributes: [[models.sequelize.fn('sum', models.sequelize.col('payments.payment_amount')), 'total_cost']]
}
],
group: ['contracts.id']
})