How to get a distinct count with sequelize?

前端 未结 3 1715
情深已故
情深已故 2021-02-12 02:45

I am trying to get a distinct count of a particular column using sequelize. My initial attempt is using the \'count\' method of my model, however it doesn\'t look like this is

相关标签:
3条回答
  • 2021-02-12 03:11

    Looks like this is now supported in Sequelize versions 1.7.0+.

    the count and findAndCountAll methods of a model will give you 'real' or 'distinct' count of your parent model.

    0 讨论(0)
  • 2021-02-12 03:12

    UPDATE: New version

    As mentioned in the comments, things have changed since my original post. There is now separate distinct and col options. The docs for distinct state:

    Apply COUNT(DISTINCT(col)) on primary key or on options.col.

    It appears, you now want something along the lines of:

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

    Original Post

    After looking at Model.count method in lib/model.js, and tracing some code, I found that when using Model.count, you can just add any kind of aggregate function arguments supported by MYSQL to your options object. The following code will give you the amount of different values in MyModel's someColumn:

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

    That code effectively generates a query of this kind: SELECT COUNT(args) FROM MyModel WHERE ..., where args are all properties in the options object that are not reserved (such as DISTINCT, LIMIT and so on).

    0 讨论(0)
  • 2021-02-12 03:15

    The Sequelize documentation on count links to a count method that doesn't let you specify which column to get the count of distinct values:

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

    Basically SELECT COUNT(DISTINCT(*)) or SELECT COUNT(DISTINCT(primaryKey)) if you've got a primary key defined.

    To do the Sequelize equivalent of SELECT category, COUNT(DISTINCT(product)) as 'countOfProducts' GROUP BY category, you'd do:

    model.findAll({
      attributes: [
        'category',
        [Sequelize.literal('COUNT(DISTINCT(product))'), 'countOfProducts']
      ],
      group: 'category'
    })
    
    0 讨论(0)
提交回复
热议问题