web-dev-qa-db-ja.com

sequelizeで個別のカウントを取得する方法は?

Sequelizeを使用して特定の列の個別のカウントを取得しようとしています。私の最初の試みは、私のモデルの「カウント」メソッドを使用していますが、これが可能であるように見えません。

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 );
19
Adam

これは、Sequelizeバージョン1.7.0以降でサポートされるようになりました。

モデルのcountおよびfindAndCountAllメソッドは、親モデルの「実際の」または「個別の」カウントを提供します。

5
Adam

更新:新しいバージョン

コメントで述べたように、私の最初の投稿以来、状況は変わっています。現在、個別のdistinctオプションとcolオプションがあります。 distinctのドキュメント 状態:

主キーまたはoptions.colにCOUNT(DISTINCT(col))を適用します。

次のように表示されるようになりました。

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

オリジナルポスト

lib/model.jsのModel.countメソッド を見て、いくつかのコードをトレースした後、Model.count、MYSQLがサポートする任意の種類の集約関数引数をオプションオブジェクトに追加できます。次のコードは、MyModelsomeColumnのさまざまな値の量を示します。

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

そのコードは、この種のクエリを効果的に生成します。SELECT COUNT(args) FROM MyModel WHERE ...argsは、予約されていないオプションオブジェクトのすべてのプロパティです(DISTINCTLIMITなど)オン)。

22
Domi

countのドキュメントをシークライズカウントメソッド にリンクしているため、個別の値のカウントを取得する列を指定できません。

_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))は、主キーが定義されている場合に使用します。

SELECT category, COUNT(DISTINCT(product)) as 'countOfProducts' GROUP BY categoryと同等のSequelizeを実行するには、次のようにします。

_model.findAll({
  attributes: [
    'category',
    [Sequelize.literal('COUNT(DISTINCT(product))'), 'countOfProducts']
  ],
  group: 'category'
})
_
5
user941238