1

CTEベースのクエリがあり、結合を使用して約2600の4タプルの緯度/経度の値を渡します。これらの緯度経度の4タプルは、IDタグが付けられ、座標と呼ばれる2番目のテーブルに保持されています。これらの左上と右下の緯度/経度の値は、指定された2つのタイムスタンプの座標内で行われたリクエストの量(1時間ごと)を表示するためにCTEに渡されます)-タイムスタンプ内の1日あたりのリクエストの合計を取得できますつまり、指定された日ごとのユーザー要求の総数です。(たとえば、ユーザーは毎週水曜日または水曜日と木曜日などを表示することを選択します。通過するすべての緯度/経度4タプルについて、2012年1月1日から31日までの11:55から22:04の時間の間。)しかし、行を取得できません。結果でzcountが0の場合、zcount>0の行のみが取得されます。クエリは次のとおりです。Erwin Brandstetterがこれを見たら、前の質問についてチャットルームのディスカッションを確認し、座標は設計によるものである可能性があると言ったためにcoordinates値を設定しましたが、それでも同じ問題が発生します。-当時、熱がひどい状態で倒れていたので、あなたが間違っていると思っていたかもしれませんが-NOT NULLnull

WITH v AS (
   SELECT '2012-1-1 11:55:11'::timestamp AS _from -- provide times once
         ,'2012-1-31 22:02:21'::timestamp AS _to
   )
, q AS (
   SELECT c.coordinates_id
        , date_trunc('hour', t.calltime) AS stamp
        , count(*) AS zcount
   FROM   v
   JOIN   mytable t ON  t.calltime BETWEEN v._from AND v._to
                   AND (t.calltime::time >= v._from::time AND
                        t.calltime::time <= v._to::time) AND 
(extract(DOW from t.calltime) = 3)
   JOIN   coordinates c ON (t.lat, t.lon) 
                   BETWEEN (c.bottomrightlat, c.topleftlon)
                       AND (c.topleftlat, c.bottomrightlon)
   GROUP BY c.coordinates_id, date_trunc('hour', t.calltime)
   )
, cal AS (
   SELECT generate_series('2012-1-1 11:00:00'::timestamp
                        , '2012-1-31 23:00:00'::timestamp
                        , '1 hour'::interval) AS stamp)
SELECT q.coordinates_id, cal.stamp::date, sum(q.zcount) AS zcount
FROM   v, cal
LEFT   JOIN q USING (stamp)
WHERE  extract(hour from cal.stamp) BETWEEN extract(hour from v._from)
                                        AND extract(hour from v._to)
AND    extract(DOW from cal.stamp) = 3 
AND    cal.stamp >= v._from
AND    cal.stamp <= v._to
GROUP  BY 1,2
ORDER  BY 1,2;

このクエリを実行したときに得られる出力は、基本的に次のようになります(通常、類似性のために2つの座標を提供するだけで、zcountが0の行を除いて約10354行が返されます)。

coordinates_id  | stamp      | zcount
1               ;"2012-01-04";      2
1               ;"2012-01-11";      3
1               ;"2012-01-18";      2
2               ;"2012-01-04";      2
2               ;"2012-01-11";      3
2               ;"2012-01-18";      2

ただし、zcount 0のすべての行が、ゼロ以外のzcountを持つ行と一緒に印刷される必要がある場合は、次のようになります。たとえば、ID1と2の2つの座標のzcount0の1月25日も、この小さな部分に印刷されます。例-:

coordinates_id  | stamp      | zcount
1               ;"2012-01-04";      2
1               ;"2012-01-11";      3
1               ;"2012-01-18";      2
1               ;"2012-01-25";      0
2               ;"2012-01-04";      2
2               ;"2012-01-11";      3
2               ;"2012-01-18";      2
2               ;"2012-01-25";      0

zcount値が実際よりもはるかに大きい更新バージョン。-また、zcountが0の行はまだ表示されません-

WITH v AS (
   SELECT '2012-1-1 11:55:11'::timestamp AS _from -- provide times once
         ,'2012-1-31 22:02:21'::timestamp AS _to
   )
, q AS (
   SELECT c.coordinates_id
        , date_trunc('hour', t.calltime) AS stamp
        , count(*) AS zcount
   FROM   v
   JOIN   mytable t ON  t.calltime BETWEEN v._from AND v._to
                   AND (t.calltime::time >= v._from::time AND
                        t.calltime::time <= v._to::time) AND 
(extract(DOW from t.calltime) = 3)
   JOIN   coordinates c ON (t.lat, t.lon) 
                   BETWEEN (c.bottomrightlat, c.topleftlon)
                       AND (c.topleftlat, c.bottomrightlon)
   GROUP BY c.coordinates_id, date_trunc('hour', t.calltime)
   )
, cal AS (
   SELECT generate_series('2012-1-1 11:00:00'::timestamp
                        , '2012-1-31 23:00:00'::timestamp
                        , '1 hour'::interval) AS stamp)
, coordst AS ( 
   SELECT coordinates_id FROM coordinates)
SELECT q.coordinates_id, cal.stamp::date, COALESCE(sum(q.zcount),0) AS zcount
FROM   v, coordst, cal
LEFT   JOIN q USING (stamp)
WHERE  extract(hour from cal.stamp) BETWEEN extract(hour from v._from)
                                        AND extract(hour from v._to)
AND    extract(DOW from cal.stamp) = 3 
AND    cal.stamp >= v._from
AND    cal.stamp <= v._to
GROUP  BY 1,2
ORDER  BY 1,2;
4

1 に答える 1

1

適切なCROSSJOINを実行するには、coordinates_idの個別のリストが必要です。1.WITHに別のエントリを追加します。2.それをJOIN(FROM v、cal、coords)に追加します。3. zcountはNULLと表示されるので、それをCOALESCEします。

WITH v AS (
   SELECT '2012-1-1 11:55:11'::timestamp AS _from -- provide times once
         ,'2012-1-31 22:02:21'::timestamp AS _to
   )
, q AS (
   SELECT c.coordinates_id
        , date_trunc('hour', t.calltime) AS stamp
        , count(*) AS zcount
   FROM   v
   JOIN   mytable t ON  t.calltime BETWEEN v._from AND v._to
                   AND (t.calltime::time >= v._from::time AND
                        t.calltime::time <= v._to::time) AND 
(extract(DOW from t.calltime) = 3)
   JOIN   coordinates c ON (t.lat, t.lon) 
                   BETWEEN (c.bottomrightlat, c.topleftlon)
                       AND (c.topleftlat, c.bottomrightlon)
   GROUP BY c.coordinates_id, date_trunc('hour', t.calltime)
   )
, cal AS (
   SELECT generate_series('2012-1-1 11:00:00'::timestamp
                        , '2012-1-31 23:00:00'::timestamp
                        , '1 hour'::interval) AS stamp)
, coordst AS ( 
   SELECT DISTINCT coordinates_id FROM coordinates)
SELECT coordst.coordinates_id, cal.stamp::date, COALESCE(sum(q.zcount),0) AS zcount
FROM   v CROSS JOIN coordst CROSS JOIN cal
LEFT   JOIN q USING q.stamp = cal.stamp AND coordst.coordinates_id = q.coordinates_id
WHERE  extract(hour from cal.stamp) BETWEEN extract(hour from v._from)
                                        AND extract(hour from v._to)
AND    extract(DOW from cal.stamp) = 3 
AND    cal.stamp >= v._from
AND    cal.stamp <= v._to
GROUP  BY 1,2
ORDER  BY 1,2;
于 2012-10-06T16:00:13.320 に答える