0

我有一张表,我计算一个元素出现的频率。为此,我可以使用Sequel::Dataset#group_and_count.

但现在我想计算这个结果。我怎样才能做到这一点?

例子

require 'sequel'
Sequel.extension :pretty_table
DB = Sequel.sqlite()

DB.create_table( :test ){
  add_field :key,    :type => :nvarchar, :size => 10
  add_field :value, :type => :nvarchar, :size => 10
}

'a'.upto('f'){|a|
  a.upto('x'){|b|
    DB[:test].insert( :key => a, :value => b)
  }
}

sel = DB[:test].group_and_count(:key)
puts  Sequel::PrettyTable.string(sel) 

这给了我:

+-----+---+
|count|key|
+-----+---+
|   24|a  |
|   23|b  |
|   22|c  |
|   21|d  |
|   20|e  |
|   19|f  |
+-----+---+

现在我想计算一个计数值出现的频率。

我的结果应该是:

+-----------+-----+
|count_value|count|
+-----------+-----+
|   24      |  1  |
|   23      |  1  |
|   22      |  1  |
|   21      |  1  |
|   20      |  1  |
|   19      |  1  |
+-----------+-----+

我可以得到这个结果:

mycount = Hash.new(0)
DB[:test].group_and_count(:key).each{| res |
  mycount[res[:count]] += 1
}
p mycount # {24=>1, 23=>1, 22=>1, 21=>1, 20=>1, 19=>1}

使用 SQL(请参阅SQL Group by Count of Counts)我可以执行以下命令:

puts DB.fetch(<<-sql ).all
  select count_value, count(*) as count from (
    select count(*) as count_value from test group by key
  )
  group by count_value
sql

但我正在寻找一种使用 Sequel 命令(如果可能的话)来执行此操作的方法。

我尝试了什么:

group_and_count不可链接:

#SQLite3::SQLException: no such column: count (Sequel::DatabaseError)
sel = DB[:test].group_and_count(:key).group_and_count(:count)

也无法重命名 :count

sel = DB[:test].group_and_count(:key).select(:count.as(:count_value))

如果我定义一个视图,我会得到一个 DatabaseError:

DB.create_view(:count_testkey,  DB[:test].group_and_count(:key))
sel = DB[:count_testkey].group_and_count(:count)

#SQLite3::SQLException: aggregate functions are not allowed in the GROUP BY clause (Sequel::DatabaseError)
puts  Sequel::PrettyTable.string(sel) 
4

1 回答 1

0

我找到了一个解决方案:

sel = DB[:test].select(:count_value, Sequel::SQL::Function.new(:count, Sequel::Dataset::WILDCARD).as(:count)).group_by(:count_value)
.from( 
    DB[:test].select(Sequel::SQL::Function.new(:count, Sequel::Dataset::WILDCARD).as(:count_value)
        ).group_by(:key)
  )

puts sel.sql.downcase
puts  Sequel::PrettyTable.string(sel) 

这会导致(SQL 命令是“我漂亮打印的”):

select `count_value`, count(*) as 'count' from (
  select count(*) as 'count_value' from `test` group by `key`) as 't1' 
group by `count_value`
+-----+-----------+
|count|count_value|
+-----+-----------+
|    1|         19|
|    1|         20|
|    1|         21|
|    1|         22|
|    1|         23|
|    1|         24|
+-----+-----------+

基于此解决方案,我定义了一种新方法Sequel::Dataset#group_and_countcount

这里有一个完整的例子:

require 'sequel'
Sequel.extension :pretty_table
DB = Sequel.sqlite()

DB.create_table( :test ){
  add_field :key,    :type => :nvarchar, :size => 10
  add_field :value, :type => :nvarchar, :size => 10
}

'a'.upto('f'){|a|
    a.upto('x'){|b|
      DB[:test].insert( :key => a, :value => b)
      DB[:test].insert( :key => 'x', :value => b) if a == 'a' #force one double count
    }
}

puts "Test DB[:test].group_and_count(:key)"
sel = DB[:test].group_and_count(:key)
puts  Sequel::PrettyTable.string(sel) 

module Sequel
  class Dataset
    def group_and_countcount(key)
      self.unfiltered.select(:count_value, Sequel::SQL::Function.new(:count, Sequel::Dataset::WILDCARD).as(:count)).group_by(:count_value)
        .from( 
            self.select(Sequel::SQL::Function.new(:count, Sequel::Dataset::WILDCARD).as(:count_value)
                ).group_by(key)
          )
    end #group_and_countcount(key)
  end
end

puts "Test DB[:test].group_and_countcount(:key)"
sel = DB[:test].group_and_countcount(:key)
puts  Sequel::PrettyTable.string(sel) 

结果:

Test DB[:test].group_and_count(:key)
+-----+---+
|count|key|
+-----+---+
|   24|a  |
|   23|b  |
|   22|c  |
|   21|d  |
|   20|e  |
|   19|f  |
|   24|x  |
+-----+---+
Test DB[:test].group_and_countcount(:key)
+-----+-----------+
|count|count_value|
+-----+-----------+
|    1|         19|
|    1|         20|
|    1|         21|
|    1|         22|
|    1|         23|
|    2|         24|
+-----+-----------+
于 2013-08-14T21:02:27.027 回答