2011-06-14 5 views
0

3 (또한 당신의 쿼리를 사용하여 같은 느낌이 경우 meta_where 보석과), 내가 내 머리를 두드리는 된 정말 복잡한 쿼리를 가지고 :까다로운 Rails3/MySQL의 쿼리 레일에서

은 가정하자 내가 두가를 모델, 고객 및 구매, 고객이 많은 구매를했습니다. 'repeat_customer'로 최소 2 회 이상 구매 한 고객을 정의 해 보겠습니다. 나는 최근 3 개월 동안 매일에 의해 repeat_customers의 총 수를 찾을 필요가, 무엇인가 : 그 때 이후 나는 자신의 두 번째 구매의 창조의 날짜를 기준으로 그룹의 고객 수에 필요한 기본적

Date TotalRepeatCustomerCount 
1/1/11 10 (10 repeat customers by the end of 1/1/11) 
1/2/11 15 (5 more customer gained "repeat" status on this date) 
1/3/11 16 (1 more customer gained "repeat" status on this date) 
... 
3/30/11 150 
3/31/11 160 

그들은 "반복적 인 상태를 얻는다". 물론이 루비에 달성 할 수

, 같은 :

Customer.includes(:purchases).all.select{|x| x.purchases.count >= 2 }.group_by{|x| x.purchases.second.created_at.to_date }.map{|date, customers| [date, customers.count]} 

그러나, 위의 코드는 Customer.allPurchase.all의 같은 라인의 쿼리를 실행됩니다 후 루비에서 계산 한 무리을한다. 훨씬 빠를뿐 아니라 데이터베이스에서 대역폭을 줄이기 때문에 mysql에서 선택, 그룹화 및 계산을하는 것을 선호한다. 대형 데이터베이스에서 위의 코드는 기본적으로 쓸모가 없습니다.

필자는 rails/active_record에서 쿼리를 작성하는 동안 잠시 노력했지만 멋진 meta_where gem을 사용해도 운이 없다. 내가해야한다면, 나는 순수한 mysql 쿼리의 해결책을 받아 들일 것이다.

편집 :이 단순화 된 문제에 대해서만 캐시 (또는 고객에게 "반복"필드 추가)합니다. 반복 고객에 대한 기준은 어느 시점 (2 건의 구매, 3 건의 구매, 4 건의 구매 등)에서 고객이 변경할 수 있으므로 불행히도 그 자리에서 계산해야합니다.

+0

이 정보를 캐시하고 구매시 생성하는 테이블을 만들 수 있습니까? 그렇게하면 계산상의 오버 헤드가 없으며 사용자의 상태를 한 번만 계산하면됩니다. –

+0

이것은 직접적으로 대답하지 않지만 Devin의 의견을 바탕으로 repeat_status_date라는 열을 고객에게 추가하고 after_save 콜백을 사용하여 구매 객체에 작성할 수 있습니다. –

+0

이 단순화 된 문제에 대해서만 캐시 (또는 고객에게 "반복"필드 추가). 반복 고객에 대한 기준은 어느 시점 (2 건의 구매, 3 건의 구매, 4 건의 구매 등)에서 고객이 변경할 수 있으므로 불행히도 그 자리에서 계산해야합니다. – Charles

답변

0
SELECT p_date, COUNT(customers.id) FROM 
(
    SELECT p_date - INTERVAL 1 day p_date, customers.id 
    FROM 
    customers NATURAL JOIN purchases 
    JOIN (SELECT DISTINCT date(purchase_date) p_date FROM purchases) p_dates 
    WHERE purchases.purchase_date < p_date 
    GROUP BY p_date, customers.id 
    HAVING COUNT(purchases.id) >= 2 
) a 
GROUP BY p_date 

나는 조금이 테스트를하지 않았다, 그래서 그것을 작동 바랍니다. 또한, 당신이 성취하고자하는 것을 이해하기를 바랍니다.

하지만 너무 길어서는 안되기 때문에주의하시기 바랍니다. 하루가 지나면 데이터가 변경되지 않으므로 매일 데이터를 캐시합니다.

+0

이 단순화 된 문제에 대해서만 캐시를 만들거나 고객에게 "반복"필드를 추가합니다. 반복 고객에 대한 기준은 어느 시점 (2 건의 구매, 3 건의 구매, 4 건의 구매 등)에서 고객이 변경할 수 있으므로 불행히도 그 자리에서 계산해야합니다. – Charles

+0

이 코드가 작동하면 다시 듣는 것이 좋을 것입니다. – Ariel