PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Връщане на дублирани записи (activerecord, postgres)

По SQL-y начин

Първо, нека просто разрешим проблема в SQL, така че специфичният за Rails синтаксис да не ни подведе.

Този SO въпрос е доста ясен паралел:Намиране на дубликат стойности в SQL таблица

Отговорът от KM (втори отгоре, без отметка, в момента) отговаря на вашите критерии за връщане на всички дублирани записи заедно с техните идентификатори. Промених KM SQL да съответства на вашия маса...

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

Частта вътре в INNER JOIN ( ) е по същество това, което вече сте генерирали. Групирана таблица с дублирани заглавия и бройки. Номерът е JOIN като го прехвърлите към немодифицираните movies таблица, която ще изключи всички филми, които нямат съвпадения в заявката за дупки.

Защо това е толкова трудно да се генерира в Rails? Най-сложната част е това, защото ние сме JOIN снимане на movies към movies , трябва да създадем псевдоними на таблици (m и dupes в моята заявка по-горе).

За съжаление, Rails не предоставя чисти начини за деклариране на тези псевдоними. Някои препратки:

За щастие, тъй като имаме SQL под ръка, можем да използваме .find_by_sql метод...

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")

Защото извикваме Movie.find_by_sql , ActiveRecord предполага, че нашият ръкописен SQL може да бъде включен в Movie обекти. Не масажира и не генерира нищо, което ни позволява да създаваме нашите псевдоними.

Този подход има своите недостатъци. Той връща масив, а не релация ActiveRecord, което означава, че не може да бъде свързан с други обхвати. И в документацията за find_by_sql метод , получаваме допълнително обезсърчение...

A Rails-y Way

Наистина, какво прави SQL по-горе? Получава списък с имена, които се появяват повече от веднъж. След това съпоставя този списък с оригиналната таблица. Така че, нека просто направим това с помощта на Rails.

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

Movie.where(title: titles_with_multiple)

Ние наричаме .keys защото първата заявка връща хеш. Ключовете са нашите заглавия. where() може да приеме масив и ние сме му дали масив от заглавия. Победител.

Може да се твърди, че една линия Ruby е по-елегантна от две. И ако този един ред на Ruby има безбожен низ от SQL, вграден в него, колко елегантен е той наистина?

Надявам се това да помогне!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка при неуспешно удостоверяване на паролата при стартиране на миграцията на laravel

  2. Rails:Разгръщане в Heroku, много проблеми

  3. Rails:Преобразуването от MySQL в PostGres прекъсва изчисленията на разстоянието на Geokit?

  4. Прикачете дял LIST към съществуваща таблица в postgres 11

  5. Радио бутони ng-проверени с ng-model