2014-03-25 20 views
6

我想使用sequelize獲得特定列的不同數量。我最初的嘗試是使用我的模型的'count'方法,但它看起來不像這是可能的。如何獲得一個明確的計數與續集?

DISTINCT功能是必需的,因爲我加入其他表並根據相關表過濾父項的行。

這裏的查詢,我想:

SELECT COUNT(DISTINCT Product.id) as `count` 
FROM `Product` 
LEFT OUTER JOIN `Vendor` AS `vendor` ON `vendor`.`id` = `Product`.`vendorId` 
WHERE (`vendor`.`isEnabled`=true); 

使用下面的查詢對我的產品型號:

Product.count({ 
     include: [{model: models.Vendor, as: 'vendor'}], 
     where: [{ 'vendor.isEnabled' : true }] 
    }) 

生成以下查詢:

SELECT COUNT(*) as `count` 
FROM `Product` 
LEFT OUTER JOIN `Vendor` AS `vendor` ON `vendor`.`id` = `Product`.`vendorId` 
WHERE (`vendor`.`isEnabled`=true); 
+1

爲什麼不直接使用存儲過程和調用它呢?根據這個changelog(http://sequelizejs.com/changelog/v1-6-0)sequelize支持存儲過程。然後,您可以以最適合您的需求的方式編寫查詢,併爲您正在使用的數據庫進行優化。 – dcp

+0

這可能是一個有效的解決方案,你是否說沒有其他方式在計數操作中包含DISTINCT? – Adam

+0

我不知道任何其他方式,但其他人可能有想法的方法來做到這一點。一般來說,我嘗試使用存儲過程來處理所有與數據庫相關的代碼,這是因爲這樣的原因。無論我碰巧使用哪種前端技術,我都會使用這種方法。真正好的是,您可以重複使用該存儲過程,因爲針對您的數據庫使用了不同的前端技術。 – dcp

回答

4

看起來這是現在支持Sequelize 1.7.0+版本。

countfindAndCountAll模型的方法會給你父母模型的「真實」或「不同」數。

+1

我剛剛開始使用Sequelize,但不應該是'findAndCountAll'?也許方法名稱現在和兩年前有所不同。讓知道此事的人知道。 –

8

更新:新版本

我用下面的方法早在天,它工作得很好,然而由於在評論中提到的,事情從此改變。如文檔所述,distinct

在主鍵或options.col上應用COUNT(DISTINCT(col))。

它的出現,你現在想沿着線的東西:

MyModel.count({ 
    include: ..., 
    where: ..., 
    distinct: true, 
    col: 'Product.id' 
}) 
.then(function(count) { 
    // count is an integer 
}); 

原貼

看着Model.count method in lib/model.js,並跟蹤一些代碼後,我發現,使用Model.count時,您可以將任何種類的由MYSQL支持的聚合函數參數添加到您的選項對象中。下面的代碼會給你不同的值的量MyModelsomeColumn

MyModel.count({distinct: 'someColumn', where: {...}}) 
.then(function(count) { 
    // count is an integer 
}); 

該代碼有效地產生這樣的查詢:SELECT COUNT(args) FROM MyModel WHERE ...,其中args都在選擇對象的所有屬性沒有被保留(如DISTINCT,LIMIT等)。

+1

實際上,distinct參數是一個布爾參數,它僅表示是否應使用不同的獨立參數。不同的計數總是應用在模型的主鍵上,所以這個解決方案不會相應地工作,至少不會與當前的sequelize版本。 – Florian

2

Sequelize documentation on count鏈接a count method不會讓您指定要獲得不同值的計數的列:

Model.prototype.count = function(options) { 
    options = Utils._.clone(options || {}); 
    conformOptions(options, this); 
    Model.$injectScope(this.$scope, options); 
    var col = '*'; 
    if (options.include) { 
    col = this.name + '.' + this.primaryKeyField; 
    expandIncludeAll.call(this, options); 
    validateIncludedElements.call(this, options); 
    } 
    Utils.mapOptionFieldNames(options, this); 
    options.plain = options.group ? false : true; 
    options.dataType = new DataTypes.INTEGER(); 
    options.includeIgnoreAttributes = false; 
    options.limit = null; 
    options.offset = null; 
    options.order = null; 
    return this.aggregate(col, 'count', options); 
}; 

基本上SELECT COUNT(DISTINCT(*))SELECT COUNT(DISTINCT(primaryKey))如果你有定義了主鍵。

要做到Sequelize相當於SELECT category, COUNT(DISTINCT(product)) as 'countOfProducts' GROUP BY category,你會怎麼做:

model.findAll({ 
    attributes: [ 
    'category', 
    [Sequelize.literal('COUNT(DISTINCT(product))'), 'countOfProducts'] 
    ], 
    group: 'category' 
}) 
相關問題