2017-11-23 6 views
0

GroupBy gemを使用してデータベース内の過去3日間(今日)レコードのアクティビティが存在する日数を調べるクエリを実行しています日ごとにグループ化します。ここでは、完全なクエリは次のとおりです。countメソッドは、条件の日付によって異なる値を返します。

Record.activities.where("created_at >= ?", 2.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count.count 

2日前、私は今日の0を持っていると、昨日、1つの活性を有している私がいる2.これは2(いない3、それは日ではない活動を数えています)が、ために返す必要があります何らかの理由で3が返ってきます。私が2.days.ago1.day.agoまたは0.days.agoに変更すると、正しい値1が返されます。アクティビティが存在しなかった昨日は無視され、その日が今日認識された日だけがカウントされます。アクティビティ。

私は二.countを削除する場合は、ここで

{Tue, 21 Nov 2017=>1, Wed, 22 Nov 2017=>0, Thu, 23 Nov 2017=>2} 

...それは2.days.agoのために返すものだと私は1.day.agoのためにそれを実行する場合、私が手...ここ

{Thu, 23 Nov 2017=>2} 

があります2.days.agoクエリの生のSQL ..

SELECT COUNT(*) AS count_all, strftime('%Y-%m-%d 00:00:00 UTC', created_at) 
AS strftime_y_m_d_00_00_00_utc_created_at 
FROM "activities" 
WHERE "activities"."goal_id" = ? AND (created_at >= '2017-11-21 00:00:00') 
AND (created_at IS NOT NULL) 
GROUP BY strftime('%Y-%m-%d 00:00:00 UTC', created_at) 

もう少しテストをした結果、x.days.agoのxが0である場合、0のアクティビティを持つ日を無視することに気がつきました.0のアクティビティで1日以上経過した場合、最初のアクティビティは無視されますが他の日を0でカウントしてください。

私がここで行方不明になっていることはわかりませんが、問題を見つけるのに役立ちます。

詳細情報が必要な場合はお知らせください。

+1

なぜ2回カウントされますか? –

+0

Jutは質問を更新して、第2のものが何をするのか見ることができますが、基本的に2番目の 'count'は返されたハッシュの数を数えます。 – Nathan

+0

私の最初の衝動はあなたがどこかでカウントを使用していることですが、あなたは合計を使うべきです。生のMySQLクエリを追加すると、私はさらにコメントすることができます。 –

答えて

0

私は正しい結果を返す方法を見つけましたが、なぜその初期クエリがその結果を返すのか不思議です。ここで

作品クエリです:あなたがオブジェクトをRubyとし、それらを並べ替えるために、すべてのデータをロードしながら、(SQLクエリでそれを作成する必要があるため

Record.activities.where("created_at >= ?", 4.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count.reject {|k,v| v == 0 }.count 
+1

IMO、これは、0 count_allの行を無視するフィルターを追加することでSQL照会でこれをソートする方がはるかに効率的です。 – xeon131

0

すべてのソリューションの第一は、OKではありませんスケール時にはボトルネックになります)。同じことをsqlに入れてください。私はこの1つが動作するはずだと思う:

Record.activities.where("created_at >= ? AND count_all > 0", 2.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count 

次にあなたが行数を返しますCOUNT(*) 2. SQLを得ることを期待したときに3を取得する理由について。あなたの場合、あなたはいつも3つのユニークな日を持つでしょう、3つのユニークな行(group_byそれらの一意性によってグループ化します)。あなたは、私が行をフィルタするために私のクエリに作ったとして、カウントに0を持っている、0カウント数と日数をフィルタリングする必要がありますが、それでもあなたは、以下の活動なし

テストされていないクエリと日無視する.having('count(activities.id) > 0')を使用することができます

2

カウントされています:

Record.activities 
    .select('count(activities.id) as count_all,date(activities.created_at) as day') 
    .where("created_at >= ?", 2.days.ago.beginning_of_day.in_time_zone) 
    .group('day').having('count_all > 0') 
関連する問題