itsource

Rails 3은 연결 카운트 조건에 따라 쿼리

mycopycode 2023. 9. 14. 23:14
반응형

Rails 3은 연결 카운트 조건에 따라 쿼리

mysql이 포함된 레일 3에서 고객과 구매 두 가지 모델이 있다고 가정해 보겠습니다. 구매는 분명히 고객의 것입니다.주문량이 2개 이상인 모든 고객을 찾고 싶습니다.간단하게 말씀드릴 수 있습니다.

Customer.includes(:purchases).all.select{|c| c.purchases.count > 2}

하지만 사실상 위의 선은 고객의 규모에 대해 질문을 던집니다.all과 Purchase.all을 선택한 후 루비로 "select" 타입의 처리를 수행합니다.대규모 데이터베이스에서 저는 루비로 된 이 모든 "선택" 계산을 하는 것을 피하고, mysql이 처리를 하고 자격이 있는 고객의 목록만 저에게 제공하는 것을 훨씬 선호합니다.이는 (mysql이 이를 위해 더 조정되기 때문에) 훨씬 더 빠르며 데이터베이스에서 대역폭을 크게 줄입니다.

불행하게도 저는 (psudo-code)의 라인에 있는 이것을 실현하기 위해 레일에 있는 빌딩 블록들(그룹 등)과 코드를 떠올릴 수 없습니다.

Customer.joins(:purchases).where("count(purchases) > 2").all

저는 MySql 솔루션에 만족할 것입니다. 비록 저는 레일의 우아한 프레임워크에서 이것을 이해하는 것을 훨씬 선호합니다.

이것을 작동시키기 위해 보석을 설치할 필요가 없습니다(멋있는 메타이지만)

Customer.joins(:purchases).group("customers.id").having("count(purchases.id) > ?",0)

이 부분에 대한 문서가 상당히 희박합니다.당신이 이와 비슷한 질문을 더 할 수 있다면 메타웨어를 사용해 보겠습니다.Metawhere를 사용하면 다음과 같은 작업을 수행할 수 있습니다(또는 구문이 정확한지 확실하지 않은 유사한 작업).

Customer.includes(:purchases).where(:purchases => {:count.gte => 2})

이것의 장점은 메타웨어가 여전히 ActiveRecord와 렐을 사용하여 쿼리를 수행하기 때문에 '새로운' 레일과 함께 쿼리를 수행할 수 있다는 것입니다.

추가적으로, 당신은 아마 전화를 하고 싶지 않을 것입니다..all이렇게 하면 쿼리가 데이터베이스를 ping하게 됩니다.대신, 실제로 데이터가 필요할 때까지(보기에서 또는 실제 데이터를 처리하는 다른 방법) 게으른 로딩을 사용하고 db를 누르지 않는 것이 좋습니다.

이것은 좀 더 장황하지만, 고객을 원한다면where count = 0아니면 좀 더 유연한 sql을 할 것입니다.LEFT JOIN

Customer.joins('LEFT JOIN purchases on purchases.customer_id = customers.id').group('customers.id').having('count(purchases.id) = 0').length

언급URL : https://stackoverflow.com/questions/6313621/rails-3-query-on-condition-of-an-associations-count

반응형