Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

任意の順序でデータベースレコードを選択する方法

Railsでは、IDがあれば、データベースから大量のレコードを簡単に取得できます。

Person.where(id: [1, 2, 3]).map(&:id) => [1, 2, 3]

しかし、レコードを別のに戻したい場合はどうでしょうか。 注文しますか? たぶんあなたの検索エンジンは最も関連性の高いIDを最初に返します。どのように維持しますか この順序であなたの記録?

whereを試すことができます もう一度:

Person.where(id: [2, 1, 3]).map(&:id) => [1, 2, 3]

しかし、それはまったく機能しません。では、 レコードを正しい順序で元に戻しますか?

互換性のある方法: case ステートメント

Rubyと同様に、SQLは case ... whenをサポートします ステートメント。

あまり頻繁には表示されませんが、 case ... when ステートメントはほぼ ハッシュのように動作します。 ある値を別の値にマッピングできます:

case :b
when :a then 1
when :b then 2
when :c then 3
end # => 2

そのcaseステートメントはハッシュのように見えます:

{
  :a => 1,
  :b => 2,
  :c => 3
}[:b] # => 2

したがって、キーをマップして表示される順序にマッピングする方法があります。また、データベースは、その任意の順序で結果を並べ替えて返すことができます。

それを知っていると、IDとその位置をケースに入れることができます ステートメントを作成し、SQLの orderで使用します 条項。

したがって、オブジェクトを[2、1、3]の順序で返す場合、SQLは次のようになります。

SELECT * FROM people
  WHERE id IN (1, 2, 3)
  ORDER BY CASE id
    WHEN 2 THEN 0
    WHEN 1 THEN 1
    WHEN 3 THEN 2
    ELSE 3 END;

そうすれば、レコードは正しい順序で返されます。 ケース 各IDを返される順序に変換します。

もちろん、それはばかげているように見えます。そして、そのような条項を手作業で作成するのがいかに厄介であるかを想像することができます。

しかし、あなたは持っていません 手作業で作成します。それがRubyの目的です:

lib / extends / active_record / find_by_ordered_ids.rb
module Extensions::ActiveRecord::FindByOrderedIds
  extend ActiveSupport::Concern
  module ClassMethods
    def find_ordered(ids)
      order_clause = "CASE id "
      ids.each_with_index do |id, index|
        order_clause << sanitize_sql_array(["WHEN ? THEN ? ", id, index])
      end
      order_clause << sanitize_sql_array(["ELSE ? END", ids.length])
      where(id: ids).order(order_clause)
    end
  end
end

ActiveRecord::Base.include(Extensions::ActiveRecord::FindByOrderedIds)

Person.find_ordered([2, 1, 3]) # => [2, 1, 3]

まさに私たちが望んでいた方法です!

よりクリーンなMySQL固有の方法

MySQLを使用している場合、これを行うためのよりクリーンな方法があります。 MySQLには特別なORDERBY FIELDがあります 構文:

SELECT * FROM people
WHERE id IN (1, 2, 3)
ORDER BY FIELD(id, 2, 1, 3);

Rubyから生成することもできます:

lib / extends / active_record / find_by_ordered_ids.rb
module Extensions::ActiveRecord::FindByOrderedIds
  extend ActiveSupport::Concern
  module ClassMethods
    def find_ordered(ids)
      sanitized_id_string = ids.map {|id| connection.quote(id)}.join(",")
      where(id: ids).order("FIELD(id, #{sanitized_id_string})")
    end
  end
end

ActiveRecord::Base.include(Extensions::ActiveRecord::FindByOrderedIds)

したがって、MySQLを使用していて、互換性についてあまり心配していない場合は、これが良い方法です。 これらのステートメントはログを通過するため、読みやすくなります。

レコードを特定の任意の順序で表示する場合は、Rubyで並べ替える必要はありません。小さなコードスニペットを使用すると、データベースにデータの検索、並べ替え、アプリへの返送などの優れた機能を実行させることができます。


  1. Android sqliteの降順でレコードを表示するにはどうすればよいですか?

    例に入る前に、Androidのsqliteデータベースが何であるかを知っておく必要があります。 SQLiteは、デバイス上のテキストファイルにデータを保存するオープンソースのSQLデータベースです。 Androidには、SQLiteデータベースの実装が組み込まれています。 SQLiteは、すべてのリレーショナルデータベース機能をサポートしています。このデータベースにアクセスするために、JDBC、ODBCなどのデータベースへの接続を確立する必要はありません。 この例は、Androidsqliteの降順でレコードを表示する方法について示しています。 ステップ1 − Android Studio

  2. MSSQLServerでデータベースを選択する方法

    MS SQL Serverでデータベースを選択して、以下のいずれかの方法で操作できます。 方法1:SQL ServerMangementStudioを使用する クエリを実行して、 msdb、という名前のデータベースのバックアップ履歴を選択します。 msdbを選択します 下の画像に示すように。 データベースバックアップセクションから選択 方法2:T-SQLスクリプトを使用する Use クエリを実行して、 msdb、という名前のデータベースのバックアップ履歴を選択します。 msdbを選択します 次のクエリを実行することで Exec use msdb このクエリはmsdbデータベ