【问题标题】:Using group by and joins in sequelize在 sequelize 中使用 group by 和 joins
【发布时间】:2015-03-28 04:54:36
【问题描述】:

我在 PostgreSQL 数据库上有两个表,即合同和付款。一份合同完成了多项付款。

我有以下两种型号:

 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";

我没有要求选择 payment.id,因为我必须将它包含在我的聚合或分组函数中,正如我遇到的错误中所说:

可能未处理的 SequelizeDatabaseError:错误:列“payments.id” 必须出现在 GROUP BY 子句中或用于聚合函数中

我在这里遗漏了什么吗?我正在关注this answer,但即使在那里我也不明白 SQL 请求如何有效。

【问题讨论】:

    标签: sql node.js postgresql sequelize.js


    【解决方案1】:

    您可能希望从payments 中选择并加入contracts 而不是相反的问题?

    【讨论】:

      【解决方案2】:

      你能把你的函数写成

      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']
      })
      

      【讨论】:

      • 您的意思是 'contracts.id' 而不是 'models.contracts.id' 吗?无论如何,第一个给我同样的错误,第二个抛出另一个 SQL 错误(缺少 FROM 子句)。
      【解决方案3】:

      试试

      group: ['contracts.id', 'payments.id']
      

      【讨论】:

      • 谢谢,但如果我按 'payments.id' 分组,我将无法汇总 payment.payment_amount。
      • attributes: ['payment_amount', [models.sequelize.fn('sum', models.sequelize.col('payments.payment_amount')), 'total_cost']] 怎么样。如果选择“nothing”,基本上sequelize 会选择id。如果可行,我将更新我的答案。希望是的。
      • 不幸的是,总是同样的错误:Possibly unhandled SequelizeDatabaseError: column "payments.id" must appear in the GROUP BY clause or be used in an aggregate function
      【解决方案4】:

      此问题已在 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']
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-30
        • 2023-02-26
        • 1970-01-01
        • 1970-01-01
        • 2014-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多