[ruby-on-rails] Active Record, Rails 및 Postgres로 중복 필드가 여러 개인 행 찾기

Postgres 및 Activerecord를 사용하여 여러 열에서 중복 값이있는 레코드를 찾는 가장 좋은 방법은 무엇입니까?

이 솔루션을 여기 에서 찾았 습니다 .

User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )

그러나 그것은 postgres에서 작동하지 않는 것 같습니다. 이 오류가 발생합니다.

PG :: GroupingError : ERROR : “parts.id”열이 GROUP BY 절에 나타나거나 집계 함수에 사용되어야합니다.



답변

테스트 및 작동 버전

User.select(:first,:email).group(:first,:email).having("count(*) > 1")

또한 이것은 약간 관련이 없지만 편리합니다. 각 조합이 발견 된 횟수를 확인하려면 끝에 .size를 입력하세요.

User.select(:first,:email).group(:first,:email).having("count(*) > 1").size

그러면 다음과 같은 결과 집합이 다시 표시됩니다.

{[nil, nil]=>512,
 ["Joe", "test@test.com"]=>23,
 ["Jim", "email2@gmail.com"]=>36,
 ["John", "email3@gmail.com"]=>21}

꽤 멋지다고 생각했고 전에 본 적이 없었습니다.

Taryn에 대한 신용, 이것은 그녀의 대답의 수정 된 버전입니다.


답변

POSTGRES에서 SELECT 절에 그룹화 열을 넣어야하기 때문에이 오류가 발생합니다.

시험:

User.select(:first,:email).group(:first,:email).having("count(*) > 1").all

(참고 : 테스트되지 않았으므로 조정해야 할 수 있음)

ID 열을 제거하기 위해 편집 됨


답변

전체 모델이 필요한 경우 @newUserNameHere의 답변을 기반으로 다음을 시도하십시오.

User.where(email: User.select(:email).group(:email).having("count(*) > 1").select(:email))

그러면 행의 이메일 주소가 고유하지 않은 행이 반환됩니다.

여러 속성에 대해이 작업을 수행하는 방법을 모르겠습니다.


답변

PostgreSQL 을 사용하는 경우 단일 쿼리로 모든 중복 항목을 가져 옵니다 .

def duplicated_users
  duplicated_ids = User
    .group(:first, :email)
    .having("COUNT(*) > 1")
    .select('unnest((array_agg("id"))[2:])')

  User.where(id: duplicated_ids)
end

irb> duplicated_users


답변

답변을 기반으로 @newUserNameHere 여기에 각각의 수를 표시하는 올바른 방법은

res = User.select('first, email, count(1)').group(:first,:email).having('count(1) > 1')

res.each {|r| puts r.attributes } ; nil


답변