query - having sql que hace
Usando group by y join en secuelize (4)
¿Es el problema que podría querer seleccionar de payments
y unir contracts
lugar de al revés?
Tengo dos tablas en una base de datos PostgreSQL, contratos y pagos. Un contrato tiene múltiples pagos realizados.
Estoy teniendo los dos modelos siguientes:
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;
};
Me gustaría sumar todos los pagos realizados para cada contrato, y usé esta función:
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'']
})
Pero genera la siguiente consulta:
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";
No solicito seleccionar pagos.id, porque tendría que incluirlo en mi agregación o agrupar por funciones, como se dice en el error:
Posiblemente SequelizeDatabaseError no manejado: error: la columna "payment.id" debe aparecer en la cláusula GROUP BY o debe usarse en una función agregada
Me estoy perdiendo de algo ? Estoy siguiendo esta respuesta, pero incluso allí no entiendo cómo la solicitud de SQL puede ser válida.
Este problema se ha solucionado en Sequelize 3.0.1, la clave principal de los modelos incluidos debe excluirse con
attributes: []
y la agregación debe realizarse en el modelo principal (información en este tema de github ).
Así, para mi caso de uso, el código es el siguiente
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'']
})
Puedes escribir tu función como
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'']
})
Tratar
group: [''contracts.id'', ''payments.id'']