PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Kembalikan rekaman duplikat (activerecord, postgres)

Cara SQL-y

Pertama, mari kita selesaikan masalah di SQL, sehingga sintaks khusus Rails tidak menipu kita.

Pertanyaan SO ini adalah paralel yang cukup jelas:Menemukan duplikat nilai dalam Tabel SQL

Jawaban dari KM (kedua dari atas, tidak dicentang, saat ini) memenuhi kriteria Anda untuk mengembalikan semua rekaman duplikat beserta ID-nya. Saya telah memodifikasi KM SQL untuk mencocokkan Anda meja...

SELECT
  m.id, m.title
FROM 
  movies m
INNER JOIN (
  SELECT
    title, COUNT(*) AS CountOf
  FROM
    movies
  GROUP BY 
    title
  HAVING COUNT(*)>1
) dupes 
ON
  m.title=dupes.title

Bagian di dalam INNER JOIN ( ) pada dasarnya adalah apa yang telah Anda hasilkan. Tabel yang dikelompokkan dari judul dan jumlah duplikat. Caranya adalah JOIN memasukkannya ke movies yang tidak dimodifikasi tabel, yang akan mengecualikan film apa pun yang tidak memiliki kecocokan dalam kueri penipuan.

Mengapa ini sangat sulit untuk dihasilkan di Rails? Bagian tersulitnya adalah, karena kita JOIN ing movies ke movies , kita harus membuat alias tabel (m dan dupes dalam pertanyaan saya di atas).

Sayangnya, Rails tidak menyediakan cara bersih untuk mendeklarasikan alias ini. Beberapa referensi:

Untungnya, karena kita sudah menguasai SQL, kita bisa menggunakan .find_by_sql metode...

Movie.find_by_sql("SELECT m.id, m.title FROM movies m INNER JOIN (SELECT title, COUNT(*) FROM movies GROUP BY title HAVING COUNT(*)>1) dupes ON m.first=.first")

Karena kami memanggil Movie.find_by_sql , ActiveRecord mengasumsikan SQL tulisan tangan kita dapat digabungkan ke dalam Movie objek. Itu tidak memijat atau menghasilkan apa pun, yang memungkinkan kita melakukan alias kita.

Pendekatan ini memiliki kekurangan. Ini mengembalikan array dan bukan Relasi ActiveRecord, yang berarti tidak dapat dirantai dengan cakupan lain. Dan, dalam dokumentasi untuk find_by_sql metode , kami mendapat keputusasaan ekstra...

Jalan Rel

Sungguh, apa yang dilakukan SQL di atas? Itu mendapatkan daftar nama yang muncul lebih dari sekali. Kemudian, itu mencocokkan daftar itu dengan tabel asli. Jadi, mari kita lakukan itu menggunakan Rails.

titles_with_multiple = Movie.group(:title).having("count(title) > 1").count.keys

Movie.where(title: titles_with_multiple)

Kami memanggil .keys karena kueri pertama mengembalikan hash. Kuncinya adalah gelar kami. where() metode dapat mengambil sebuah array, dan kami telah memberikannya sebuah array dari judul. Pemenang.

Anda bisa berargumen bahwa satu baris Ruby lebih elegan daripada dua baris. Dan jika satu baris Ruby itu memiliki string SQL yang tertanam di dalamnya, seberapa elegan itu sebenarnya?

Semoga membantu!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mendapatkan ukuran lob di PostgreSQL

  2. Tetapkan nilai dalam ketergantungan bagan Helm

  3. Mewakili Tanggal, Waktu, dan Interval di PostgreSQL

  4. Apakah fungsi PostgreSQL bersifat transaksional?

  5. Driver JDBC tidak tersedia untuk 'org.postgresql.Driver' untuk Spring Roo