0

plpgsql を使用してループで実行されるパラメトリック クエリを作成しようとしています。

2 つのパラメーターは、クエリに渡される開始緯度/経度ポイントになります。緯度と経度のポイントは配列から取得されるため、配列に対する foreach のような反復になり、実行ごとに 2 つの緯度/経度の値をクエリに渡します。

どうすればこのようなことをすることができますか?

私のクエリと私が考えた実装方法は次のようなものです: (X、Z の値は、渡されるパラメトリックな緯度/経度の値であり、Y と T は、私が処理する特定の計算を実行することによって取得されます)。わかりやすくするために、私のクエリは複数行と複数列の結果 (タイムスタンプとカウント) を返します。

for each latitude-longitude pair X,Z in array

find Y and T from X and Z

WITH cal AS (
    SELECT generate_series('2011-02-02 00:00:00'::timestamp ,
                           '2012-04-01 05:00:00'::timestamp , 
                           '1 hour'::interval) AS stamp
),
qqq AS (
  SELECT date_trunc('hour', calltime) AS stamp, count(*) AS zcount
  FROM mytable
  WHERE calltime >= '2011-02-13 22:55:11' 
    AND calltime <= '2012-02-13 01:02:21'
    AND (calltime::time >= '22:55:11' 
    OR calltime::time <= '01:02:21')
    AND lat >= X 
    AND lat <= Y
    AND lon >= Z
    AND lon <= T
 GROUP BY date_trunc('hour', calltime)
)
SELECT cal.stamp, COALESCE (qqq.zcount, 0) AS zcount
FROM cal
LEFT JOIN qqq ON cal.stamp = qqq.stamp
WHERE cal.stamp >= '2011-02-13 22:00:00' 
  AND cal.stamp <= '2012-02-13 01:02:21' 
  AND (
    extract ('hour' from cal.stamp) >= extract ('hour' from '2011-02-13 22:00:00'::timestamp) or
    extract ('hour' from cal.stamp) <= extract ('hour' from '2012-02-13 01:02:21'::timestamp) 
  )
ORDER BY stamp ASC;
4

1 に答える 1

2
  • 配列を関数に渡し、配列内FOR r IN SELECT * FROM unnest(the_array) LOOPの要素を渡します。ここで、 は関数の句にrあるrecord変数です。DECLAREまた

  • 関数に渡された refcursor をループします。PL/PgSQL カーソルを参照してください。

さらに良いことに、を避けて CTE にLOOP統合します。SELECT unnest(thearray)PL/PgSQL でのループは、SQL CTE での同等のループよりもはるかに遅くなります。

unnest、を参照してくださいLOOP

于 2012-09-20T23:14:47.363 に答える