কম্পিউটার

একটি নির্বিচারে ক্রম ডাটাবেস রেকর্ড নির্বাচন কিভাবে

রেলে, আপনার ডেটাবেস থেকে একগুচ্ছ রেকর্ড পাওয়া সহজ যদি আপনার কাছে তাদের আইডি থাকে:

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

কিন্তু আপনি যদি অন্যরকম রেকর্ডগুলি ফেরত পেতে চান তাহলে কী হবে৷ অর্ডার? হতে পারে আপনার সার্চ ইঞ্জিন প্রথমে সবচেয়ে প্রাসঙ্গিক আইডি ফেরত দেয়। আপনি কিভাবে রাখেন সেই ক্রমে আপনার রেকর্ড?

আপনি where চেষ্টা করতে পারেন আবার:

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

কিন্তু সেটা মোটেও কাজ করে না। তাহলে কিভাবে করবেন আপনি সঠিক ক্রমে আপনার রেকর্ড ফিরে পেতে?

সামঞ্জস্যপূর্ণ উপায়:case বিবৃতি

রুবির মতো, SQL case...when সমর্থন করে বিবৃতি।

আপনি এটি প্রায়শই দেখতে পান না, তবে case...when বিবৃতি প্রায় করতে পারে হ্যাশের মত কাজ করুন। আপনি একটি মান অন্য মান ম্যাপ করতে পারেন:

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

সেই কেস স্টেটমেন্টটি হ্যাশের মত দেখাচ্ছে:

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

সুতরাং, আপনার কাছে কী ম্যাপ করার একটি উপায় আছে যাতে সেগুলি উপস্থিত হওয়া উচিত৷ এবং আপনার ডাটাবেস সেই ইচ্ছাকৃত ক্রম অনুসারে আপনার ফলাফলগুলি সাজাতে এবং ফিরিয়ে দিতে পারে৷

এটা জেনে, আপনি আপনার আইডি এবং তাদের অবস্থান একটি case-এ রাখতে পারেন বিবৃতি, এবং এটি একটি SQL order এ ব্যবহার করুন ধারা৷

সুতরাং আপনি যদি আপনার বস্তুগুলি [2, 1, 3] ক্রমে ফেরত দিতে চান, তাহলে আপনার এসকিউএল এইরকম দেখতে পারে:

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;

এইভাবে, আপনার রেকর্ডগুলি সঠিক ক্রমে ফেরত দেওয়া হয়। The CASE প্রতিটি আইডিকে যে ক্রমে ফেরত দেওয়া উচিত সেই ক্রমে রূপান্তরিত করে৷

অবশ্যই, যে হাস্যকর দেখায়. এবং আপনি কল্পনা করতে পারেন যে এরকম একটি ধারা হাতে তৈরি করা কতটা বিরক্তিকর হবে।

কিন্তু আপনার নেই৷ এটি হাতে তৈরি করতে। রুবি এর জন্য এটিই:

lib/extensions/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 এর রয়েছে বিশেষ ORDER BY FIELD সিনট্যাক্স:

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

আপনি রুবি থেকেও এটি তৈরি করতে পারেন:

lib/extensions/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 ব্যবহার করেন এবং সামঞ্জস্য নিয়ে খুব বেশি চিন্তিত না হন, তাহলে এটি একটি ভাল উপায়। এই বিবৃতিগুলি আপনার লগের মাধ্যমে উড়ে যাওয়ায় এটি পড়া অনেক সহজ৷

আপনি যখন একটি নির্দিষ্ট, নির্বিচারে রেকর্ডগুলি প্রদর্শন করতে চান, তখন আপনাকে সেগুলিকে রুবিতে সাজাতে হবে না। একটি ছোট কোড স্নিপেটের সাহায্যে, আপনি ডাটাবেসকে তা করতে দিতে পারেন যা ভাল:আপনার অ্যাপে ডেটা খুঁজে বের করা, সাজানো এবং ফেরত দেওয়া।


  1. এক্সেলে কীভাবে হাইলাইট করবেন

  2. কিভাবে একটি MySQL ডাটাবেস ব্যাকআপ করবেন

  3. অ্যান্ড্রয়েড স্কলাইটে অবরোহী ক্রমে রেকর্ডগুলি কীভাবে দেখাবেন?

  4. এমএস এসকিউএল সার্ভারে একটি ডাটাবেস কীভাবে চয়ন করবেন