-1

私が直面している実際の戦術的な問題は、すべてのカテゴリが「デフォルト」として設定されているため、options[:category] ​​= 'default' を作成すると、カテゴリのないポイントのみが追加されることです。したがって、カテゴリ「arin」にポイントを追加すると、「デフォルト」の合計にはカウントされません。したがって、NOT NULL またはカテゴリ別にすべてのテーブルを取得しようとしましたが、「arin」に対して同じ量を取得し続けます。

デフォルト: 20

アリン: 20

カテゴリが指定されていない場合、または「デフォルト」の場合は合計 40 にする必要があります。params カテゴリが「arin」の場合は 20 にする必要があります。

探している結果を得るために正しい SQL の背後にある概念を理解するのを手伝ってくれる人はいますか?

Rails と SQL は初めてです。

  def self.top_scored(options = {})
   options[:table_name] ||= :users
   options[:since_date] ||= 4.months.ago
   options[:end_date] ||=  1.month.from_now
   options[:category] ||=  nil
   options[:limit]      ||= 10

  alias_id_column = "#{options[:table_name].to_s.singularize}_id"
  if options[:table_name] == :sashes
    sash_id_column = "#{options[:table_name]}.id"
  else
    sash_id_column = "#{options[:table_name]}.sash_id"
  end

  # MeritableModel - Sash -< Scores -< ScorePoints
  sql_query = <<SQL
SELECT
  #{options[:table_name]}.id AS #{alias_id_column},
  SUM(num_points) as sum_points
FROM #{options[:table_name]}
  LEFT JOIN merit_scores ON merit_scores.sash_id = #{sash_id_column}
  LEFT JOIN merit_score_points ON merit_score_points.score_id = merit_scores.id
WHERE merit_score_points.created_at > '#{options[:since_date]}' AND merit_score_points.created_at < '#{options[:end_date]}' AND (merit_scores.category IS NOT NULL OR merit_scores.category = '#{options[:category]}')
GROUP BY #{options[:table_name]}.id, merit_scores.sash_id
ORDER BY sum_points DESC
LIMIT #{options[:limit]}
SQL

  results = ActiveRecord::Base.connection.execute(sql_query)
  results.map do |h|
    h.keep_if { |k, v| (k == alias_id_column) || (k == 'sum_points') }
  end
  results
end
  end
4

1 に答える 1

0

誰も答えず、反対票を投じただけのようです。これは、将来これに疑問を抱く人へのメッセージです。SQLステートメントを分割し、SQLの周りのレールでifステートメントを使用できることがわかりました。

  sql_query = "SELECT
                #{options[:table_name]}.id AS #{alias_id_column},
                SUM(num_points) as sum_points
              FROM #{options[:table_name]}
                LEFT JOIN merit_scores ON merit_scores.sash_id = #{sash_id_column}
                LEFT JOIN merit_score_points ON merit_score_points.score_id = merit_scores.id
              WHERE merit_score_points.created_at > '#{options[:since_date]}' AND merit_score_points.created_at < '#{options[:end_date]}' "

  if(options[:category] != nil)
    sql_query += "AND merit_scores.category = \"#{options[:category]}\" "
  end

  sql_query += "GROUP BY #{options[:table_name]}.id, merit_scores.sash_id
                ORDER BY sum_points DESC
                LIMIT #{options[:limit]} "

  results = ActiveRecord::Base.connection.execute(sql_query)
于 2014-05-28T00:32:10.813 に答える