활성 레코드, 레일 및 포스트그레스를 사용하여 여러 중복 필드가 있는 행 찾기
Postgres 및 Active record를 사용하여 여러 열의 중복 값이 있는 레코드를 찾는 가장 좋은 방법은 무엇입니까?
여기서 이 솔루션을 찾았습니다.
User.find(:all, :group => [:first, :email], :having => "count(*) > 1" )
하지만 그것은 우체국에서는 작동하지 않는 것 같습니다.다음 오류가 발생합니다.
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}
저는 그것이 꽤 멋지다고 생각했고 전에 그것을 본 적이 없었습니다.
타린에게 공을 인정합니다, 이것은 그녀의 대답을 수정한 것일 뿐입니다.
이 오류는 POSTGRES에서 그룹화 열을 SELECT 절에 넣어야 하기 때문에 발생합니다.
시도:
User.select(:first,:email).group(:first,:email).having("count(*) > 1").all
(참고: 테스트되지 않음, 조정이 필요할 수 있음)
ID 열을 제거하도록 편집됨
전체 모델이 필요한 경우 다음을 시도하십시오(@newUserName 기준).답은 이렇습니다).
User.where(email: User.select(:email).group(:email).having("count(*) > 1").select(:email))
행의 전자 메일 주소가 고유하지 않은 행을 반환합니다.
여러 속성에 대해 이 작업을 수행할 방법을 모르겠습니다.
Postgre를 사용하는 경우 단일 쿼리로 모든 중복 항목 가져오기SQL:
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
나는 제대로 하려고 애썼습니다.User
승인된 답변을 통해 반환된 모델입니다.방법:
User
.group(:first, :email)
.having("COUNT(*) > 1")
.select('array_agg("id") as ids')
.map(&:ids)
.map { |group| group.map { |id| User.find(id) } }
이렇게 하면 다음과 같이 상호 작용할 수 있는 적절한 모델이 반환됩니다.
[
[User#1, User#2],
[User#35, User#59],
]
원시 SQL에서 잘 작동:
# select array_agg(id) from attendances group by event_id, user_id having count(*) > 1;
array_agg
---------------
{3712,3711}
{8762,8763}
{7421,7420}
{13478,13477}
{15494,15493}
위의 @itsnikolay 답변을 기반으로 하지만 ActiveRecord 범위를 전달할 수 있는 방법을 만듭니다.
#pass in a scope, and list of columns to group by
# map(&:dupe_ids) to see your list
def duplicate_row_ids(ar_scope, attrs)
ar_scope
.group(attrs)
.having("COUNT(*) > 1")
.select('array_agg("id") as dupe_ids')
end
#initial scope to narrow where you want to look for dupes
ar_scope = ProductReviews.where( product_id: "194e676b-741e-4143-a0ce-10cf268290bb", status: "Rejected")
#pass the scope, and list of columns to group by
results = duplicate_row_ids(ar_scope, [:nickname, :overall_rating, :source, :product_id, :headline, :status])
#get your list
id_pairs = results.map &:dupe_ids
#each entry is an array
#then go through your pairs and take action
@newUserName의 위 답변을 기반으로 합니다.여기서 나는 각각의 숫자를 보여주는 올바른 방법이라고 생각합니다.
res = User.select('first, email, count(1)').group(:first,:email).having('count(1) > 1')
res.each {|r| puts r.attributes } ; nil
언급URL : https://stackoverflow.com/questions/21669202/find-rows-with-multiple-duplicate-fields-with-active-record-rails-postgres
'programing' 카테고리의 다른 글
Android Studio 프로젝트 구조(v.s. Eclipse 프로젝트 구조) (0) | 2023.05.01 |
---|---|
Python 2.7에서 인쇄된 괄호가 자발적인 이유는 무엇입니까? (0) | 2023.05.01 |
MVVM을 사용하여 "창 닫기" 명령 구현 (0) | 2023.05.01 |
Postgre에서 기존 *.sql 파일을 가져오는 방법SQL 8.4? (0) | 2023.05.01 |
테이블의 모든 값을 SQL의 다른 테이블에 삽입 (0) | 2023.05.01 |