Sha256: d8be2af227fd80fbf9938cc0a60ac3596c57a956335c874230a9114cba5ed723

Contents?: true

Size: 1.17 KB

Versions: 1

Compression:

Stored size: 1.17 KB

Contents

module ActiveMedian
  module Model
    def median(column)
      group_values = all.group_values

      relation =
        case connection.adapter_name
        when /mysql/i
          if group_values.any?
            over = "PARTITION BY #{group_values.join(", ")}"
          end

          select(*group_values, "PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY #{column}) OVER (#{over})").unscope(:group)
        when /sqlite/i
          select(*group_values, "MEDIAN(#{column})")
        else
          select(*group_values, "PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY #{column})")
        end

      result = connection.select_all(relation.to_sql)

      # typecast
      rows = []
      columns = result.columns
      cast_method = ActiveRecord::VERSION::MAJOR < 5 ? :type_cast : :cast_value
      result.rows.each do |untyped_row|
        rows << (result.column_types.empty? ? untyped_row : columns.each_with_index.map { |c, i| untyped_row[i] ? result.column_types[c].send(cast_method, untyped_row[i]) : untyped_row[i] })
      end

      if group_values.any?
        Hash[rows.map { |r| [r.size == 2 ? r[0] : r[0..-2], r[-1]] }]
      else
        rows[0] && rows[0][0]
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
active_median-0.2.0 lib/active_median/model.rb