【问题标题】:Sequelize select distinct rows续集选择不同的行
【发布时间】:2012-08-22 18:44:18
【问题描述】:

有没有办法使用 sequelize.js 从表中选择不同的行? 我查看了文档,但“查找器方法”没有指定完成此任务的方法。

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    假设您想将 DISTINCT 应​​用于以下查询:

    Tuple.findAll({attributes: ['key', 'value']});
    

    那么这是一种(hackish)方式来实现您想要的,而无需自己编写整个查询:

    Tuple.findAll({attributes: [[Sequelize.literal('DISTINCT `key`'), 'key'], 'value']});
    

    (使用 Sequelize v2.1.0 测试)

    编辑 2015-06-08:仍然适用于 Sequelize v3.1.1

    【讨论】:

      【解决方案2】:

      您可以执行以下操作:

      myModel.findAll({
        attributes: [[sequelize.fn('DISTINCT', sequelize.col('col_name')), 'alias_name']],
        where:{}
      }).then(data => {}).....
      

      取自issues,它可以工作。

      【讨论】:

      • 注意:此解决方案不适用于 findAndCountAll 方法。
      【解决方案3】:

      编辑你的“node_modules/sequelize/lib/dialects/mysql/query-generator.js”

      在 118 号线附近

      改变

      var query = "SELECT <%= attributes %> FROM <%= table %>"
      

      进入

      var query = "SELECT " + ((options.distinct)? 'DISTINCT ':'') +"<%= attributes %> FROM <%= table %>",
      

      现在您可以在续集请求中添加选项distinct: true

      希望对你有帮助-_^

      【讨论】:

      • (...不要这样做。下次更新包时会被覆盖。)
      【解决方案4】:

      这是不可能的,但如果你不介意自己创建 sql,你可以这样做:

      sequelize.query('sql goes here', null, { raw: plain }).success(function(data){
          console.log(data)
      })
      

      玩得开心:)

      更新

      1. Sequelize 现在使用 then 而不是 success 作为 promise 函数。
      2. Sequelize.query 已被重构为仅使用参数 sqloptions
      3. raw 接受 true/false 但不接受 plain 作为值。

      所以,根据新版本,代码应该是这样的:

          sequelize.query('sql goes here', { raw: true }).then(function(data){
              console.log(data);
          });
      

      【讨论】:

      • 好的。我明白了 :) 可能在下一个版本中,可以添加一个布尔选项 {distinct: true}(默认为 false)。
      • 是的,不确定它是否会出现在下一个版本中,但我们应该添加它
      • stackoverflow.com/a/30070249/1353897 是最优雅的解决方案
      【解决方案5】:
      Model.findAll({Attributes: ['col_name1', 'col_name2'], group: ['col_name1', 'col_name2']});
      

      Sequelize 5.21 完全没问题

      【讨论】:

      • 你知道如果属性中有“不同”怎么办? Model.findAll({Attributes: [[Sequelize.fn('DISTINCT', Sequelize.col('id')), 'id'], 'col_name2'], group: ['id', 'col_name2']});
      【解决方案6】:

      这有点类似于 Pascal Ludwig 提出的解决方案,但对于那些登陆这里希望获得给定列的不同值列表的用户,您可以执行以下操作:

      MyModel.aggregate('teh_field', 'DISTINCT', { plain: false }).then(...)
      // Resolves to: [ { DISTINCT: value1 }, { DISTINCT: value2 }, ... ]
      

      这样,很容易将其转换为标准列表:

      MyModel.aggregate('teh_field', 'DISTINCT', { plain: false })
          .map(function (row) { return row.DISTINCT })
          .then(function (tehValueList) {
              // tehValueList = [ value1, value2, ... ]
          })
      ;
      

      【讨论】:

        【解决方案7】:

        从 Sequelize 1.7 版开始,选择查询已移至 lib/dialects/abstract/query-generator.js。

        1167行左右,改

        mainQueryItems.push("SELECT "+mainAttributes.join ....)

            mainQueryItems.push('SELECT ');
            if (options.distinct) {
                mainQueryItems.push('DISTINCT ');
            }
            mainQueryItems.push(mainAttributes.join(', ') + ' FROM ' + options.table);
        

        顺便说一下,我使用的是 Sqlite 和 Postgres,它们都支持“DISTINCT”。如果您使用的方言不支持 distinct,那么显然这条线会给您带来问题,因为它将为您使用的所有 SQL 风格生成。我怀疑这就是为什么这个简单的更改没有进入主 Sequelize 源代码树的原因。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-12
          • 2020-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多