1

我有一個基於CTE的查詢,我使用連接傳遞了2600個四元組緯度/經度值 - 這些緯度經度4元組已被標記並保存在稱爲座標的第二個表中。將這些左上角和右下角經度/緯度值傳遞給CTE,以便顯示在給定兩個時間戳內在這些座標內所做的請求數量(小時)).-我可以在時間戳內獲得每天的總請求數給定,即每個指定日期的用戶請求總數。 (例如,用戶選擇每個星期三或星期三和星期四等 - 在2012年1月1日和31日之間的11:55和22:04之間爲我傳遞的每個緯度/經度4元組。)但我無法獲取行在結果中,zcount爲0,我只得到zcount> 0的行。我的查詢如下:(如果他看到這個,請注意Erwin Brandstetter,我查看了關於我上一個問題的聊天室討論,並將coordinates值設置爲NOT NULL由於您說的座標可以null設計,但我仍然有同樣的問題,不知何故,用時我可能已經得到了你的意思錯誤的,因爲我發燒不好的情況下下跌了回來,則─如何使此CTE查詢打印具有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) 
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; 

我執行此查詢時得到的輸出是basicall Ÿ這樣的(通常我有大約10354行返回0 zcount不包括行,只提供兩個座標相似的緣故):

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也應該都行打印出來的行與非零zcounts - 例如1月25日,用於與ID 1和2中的兩個座標zcount 0也應打印在例 - 這個小部分:

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值比實際更大的方式。 - 還有0行的zcount仍然不顯示 -

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; 

回答

1

您需要一個不同的coordinates_id列表才能執行正確的CROSS JOIN。 1.在WITH中添加另一個條目。 2.將它添加到您的JOIN(從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; 
+0

我加了一個'COORDS AS(SELECT coordinates_id FROM座標ORDER BY coordinates_id ASC)',改變了'FROM'上面的'JOIN'到'從V,CAL,coords'但是當我運行它,現在我得到'USING子句'中指定的'ERROR:'列'stamp'不存在於左表'消息中。 - 另外,我在'SELECT'語句中用'COALESCE(sum(q.zcount),0)AS zcount'結合了zcount – sm90901

+1

USING假設使用前面的結果集。這可能只是一個progresssql錯誤,在你的FROM中翻轉座標並加入。 –

+0

我做了,現在可以工作,但結果是錯誤的。我沒有得到我在問題中指定的輸出,而是獲得了比他們應該更大的zcount值 - 同樣我仍然無法看到具有0 zcount的行,並且查詢花了很長時間才能完成 - 我編輯了問題你的解決方案建議,你能再看一次嗎? – sm90901