简体   繁体   English

使用Sequelize计算明细记录的总和和计数

[英]Calculating sum and count of detail records using Sequelize

Using Sequelize 4.1.0 , I want to produce equivalent results to this PostgreSQL 9.6.3 query: 使用Sequelize 4.1.0 ,我想产生与此PostgreSQL 9.6.3查询等效的结果:

SELECT
  "user"._id,
  "user"."lastName",
  "user"."firstName",
  "user".email,
  COALESCE(purchase.purchases, 0::bigint) - COALESCE(attendance.attendances, 0::bigint) AS balance
FROM "Users" "user"
  LEFT OUTER JOIN
    (SELECT "Purchases"."UserId", SUM("Purchases".quantity) AS purchases
    FROM "Purchases"
    GROUP BY "Purchases"."UserId") purchase ON "user"._id = purchase."UserId"
  LEFT OUTER JOIN
    (SELECT "Attendances"."UserId", COUNT("Attendances"._id) AS attendances
    FROM "Attendances"
    GROUP BY "Attendances"."UserId") attendance ON "user"._id = attendance."UserId"
    WHERE "user"."firstName" ILIKE 'Smith%' OR "user"."lastName" ILIKE 'Smith%' OR "user"."email" ILIKE 'Smith%';

My models (source: https://github.com/nstuyvesant/shy/blob/master/server/sqldb/index.js ) are defined using Sequelize 4.0.0 like this... 我的模型(来源: https : //github.com/nstuyvesant/shy/blob/master/server/sqldb/index.js )像这样使用Sequelize 4.0.0定义...

import config from '../config/environment'; // source: https://github.com/nstuyvesant/shy/blob/master/server/config/environment/index.js
import Sequelize from 'sequelize';

let db = {
  Sequelize,
  sequelize: new Sequelize(config.sequelize.uri, config.sequelize.options)
};

// Imported model definitions
db.User = db.sequelize.import('../api/user/user.model'); // source: https://github.com/nstuyvesant/shy/blob/master/server/api/user/user.model.js
db.Purchase = db.sequelize.import('../api/user/purchase.model'); // source: https://github.com/nstuyvesant/shy/blob/master/server/api/user/purchase.model.js
db.Attendance = db.sequelize.import('../api/user/attendance.model'); // source: https://github.com/nstuyvesant/shy/blob/master/server/api/user/attendance.model.js

// Associations
db.Purchase.belongsTo(db.User);
db.Attendance.belongsTo(db.User);
db.User.hasMany(db.Purchase);
db.User.hasMany(db.Attendance);

module.exports = db;

In my user API controller (source: https://github.com/nstuyvesant/shy/blob/master/server/api/user/user.controller.js ), I respond to GET /users with 在我的用户API控制器(来源: https//github.com/nstuyvesant/shy/blob/master/server/api/user/user.controller.js )中,我用来响应GET / users

import { User, Attendance, Purchase } from '../../sqldb';
import sequelize from 'sequelize';

export function index(req, res) {
  let startsWith = `${req.query.filter}%`;
  return User.findAll({
    where: {
      $or: [
        { firstName: { $iLike: startsWith } },
        { lastName: { $iLike: startsWith } },
        { email: { $iLike: startsWith } }
      ]
    },
    attributes: ['_id', 'lastName', 'firstName', 'email', [sequelize.literal('COALESCE(SUM(purchase.quantity), 0) - COALESCE(COUNT(attendance.id), 0)'), 'balance']],
    include: [{model: Purchase, attributes: ['quantity']}, {model: Attendance, attributes: ['_id']}],
    group: ['User._id', 'lastName', 'firstName', 'email', 'Purchases._id', 'Attendances._id']
  })
    .then(users => res.status(200).json(users))
    .catch(handleError(res));
}

This is the query it produces: 这是它产生的查询:

SELECT
  "User"."_id", "User"."lastName", "User"."firstName", "User"."email", COALESCE(SUM("Purchases"."quantity"), 0) - COALESCE(COUNT("Attendances"."_id"), 0) AS "balance", "Purchases"."_id" AS "Purchases._id", "Purchases"."quantity" AS "Purchases.quantity", "Attendances"."_id" AS "Attendances._id"
FROM "Users" AS "User"
  LEFT OUTER JOIN "Purchases" AS "Purchases" ON "User"."_id" = "Purchases"."UserId"
  LEFT OUTER JOIN "Attendances" AS "Attendances" ON "User"."_id" = "Attendances"."UserId"
WHERE ("User"."firstName" ILIKE 'Stuyvesant%' OR "User"."lastName" ILIKE 'Stuyvesant%' OR "User"."email" ILIKE 'Stuyvesant%')
GROUP BY "User"."_id", "lastName", "firstName", "email", "Purchases"."_id", "Attendances"."_id";

Any thoughts regarding what I might be doing wrong? 关于我可能做错了什么的任何想法?

There is the way to generate a query with difference construction but with the same result. 有一种生成具有差异构造但结果相同的查询的方法。 Supposing there were defined all models with their associations, the query will looks like following 假设定义了所有模型及其关联,查询将如下所示

User.findAll({
    attributes: ['id', 'lastName', 'firstName', 'email', [sequelize.literal('COALESCE(SUM(purchase.quantity), 0) - COALESCE(COUNT(attendance.id), 0)'), 'balance']],
    include: [{model: Purchase, attributes: 'quantity'}, {model: Attendance, attributes: 'id'}],
    group: ['id', 'lastName', 'firstName', 'email']
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM