2017-06-07 90 views
0

詳細記錄計數使用Sequelize 4.1.0,我要產生相同的結果,以這個的PostgreSQL 9.6.3查詢:計算總和和使用Sequelize

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%'; 

我的模型(來源: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; 

在我的用戶API控制器(來源:https://github.com/nstuyvesant/shy/blob/master/server/api/user/user.controller.js),我響應GET /用戶

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)); 
} 

這是查詢它產生:

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

任何想法有關我可能是做錯了什麼?

回答

0

有一種方法可以生成具有不同構造但結果相同的查詢。假設已經定義了所有與它們的關聯的模型,查詢將如下所示

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

感謝您的建議!我已更新我的帖子,以顯示更詳細的信息以及我收到的錯誤。有關我可能在哪裏實施了錯誤建議的任何想法? – nstuyvesant

+0

更改爲'include:[{model:Purchase,attributes:['quantity']},{model:Attendance,attributes:['_id']}],'我錯過了將數組傳遞給 –

+0

謝謝 - 。數組中的屬性幫助克服了錯誤。似乎生成的查詢正在生成笛卡爾積,這就是爲什麼我對產生總和和計數的查詢執行左外部連接的原因。你認爲我可能會推動Sequelize可以做什麼而無需進行原始查詢? – nstuyvesant