2017-07-02 5 views
0

私はいくつかのテーブルで大量の機能を取得しようとしています。 9.6.2の使用。複雑なSELECTのためにpsqlのARIMAYを使ってループする

私はこれらのすべての機能をさまざまなdatetimesで集めようとしています。現在のところ、私はこれを1つのタイムスタンプで実行しており、何度も呼び出す必要があります。

FROM(... UNION ...)で使用されるタイムスタンプの配列を送信したいと思います。

CREATE OR REPLACE FUNCTION features_at_times(timestamp[]) 
    RETURNS TABLE (
     str_street_id      varchar, 
     ....blahhh, blah, blah....... 
     Zone        integer, 
     DateTime       timestamp 
    ) AS 
$func$ 
DECLARE 
    stamp timestamp[]; 
    stamps timestamp[]:= array[]; 
BEGIN 
    RETURN QUERY 
    FOREACH stamp SLICE 1 IN ARRAY $1 
    LOOP 
     SELECT 
      str_stuff_id, 
      .....blahhh, blah, blah.... 
      COALESCE(MAX(zone_id), 0) "Zone", 
      MAX("DateTime") "DateTime" 

     FROM (

      SELECT 
      thingo.*, 
      str_timezone, 
      timestamp stamp AT TIME ZONE str_timezone "DateTime" 
      FROM thingo 
      JOIN destination ON pk_city = pk_destination 
      WHERE pk_city = '8fzdd56-7a52-11df-a34f-6b84rw853d3d' 
      AND thingo.pk_thingo_status = 2 

      UNION 

      SELECT 
       alt_thingo.*, 
       str_timezone, 
       timestamp stamp AT TIME ZONE str_timezone "DateTime" 
      FROM thingo 
      JOIN thingo AS alt_thingo USING (str_stuff_id) 
      JOIN destination ON thingo.pk_city = pk_destination 
      WHERE thingo.pk_city = '8fzdd56-7a52-11df-a34f-6b84rw853d3d' 
      AND thingo.pk_thingo_status = 2 

    ) as base 
     LEFT JOIN block_observation_by_bin 
      ON thingo_observation_by_bin.thingo_id = pk_thingo_id 
      AND thingo_observation_by_bin.bin_id = ((to_char("DateTime",'D')::int - 1) * 24 + to_char("DateTime", 'HH24')::int) 
      AND thingo_observation_by_bin.market_id = 94 
     LEFT JOIN block_observation 
      ON thingo_observation.thingo_id = pk_thingo_id 
      AND thingo_observation.market_id = 94 

     WHERE base.pk_thingo = '027ecb54-51ec-41a6-a57e-666fddbbff35' 
     GROUP BY str_stuff_id; 

    END LOOP; 
    END; 
$func$ LANGUAGE plpgsql; 

この同じ読みをn回必要とします。私はFOREACHが選択肢だと思っていますが、私は誤り以外何も得ていません。内部の2つのSELECTSにタイムスタンプを渡したいと思います。

また、psqlでFOREACHを使用する関数を使用する必要がありますか?

+0

代わりアンネスト使用することができ、このように 'CROSS JOINを()(アンネスト$ 1 SELECT ASスタンプ)ASスタンプ。次に、plpgsqlは必要ありません。実行するクエリは1つだけなので、 'language sql'で十分です。 –

答えて

1

RETURN QUERYの引数はSQL文でなければなりませんが、FOREACHはSQLではなくPL/pgSQLです。

また、

timestamp stamp AT TIME ZONE str_timezone "DateTime" 

が有効なSQLではありません。私はそれ以上のエラーはチェックしなかった。 1 PL/pgSQL関数で複数のテーブルから行を返すために

、あなたはこのようなカーソルでループする必要があります:

DECLARE 
    ats timestamp without time zone; 
    arow record; 
BEGIN 
    /* loop through the timestamps in the argument array */ 
    FOREACH ats IN ARRAY $1 LOOP 
     /* loop through the results of the first query */ 
     FOR arow IN 
     SELECT ... 
     LOOP 
     RETURN NEXT ...; 
     END LOOP; 
     /* loop through the results of the second query */ 
     FOR arow IN 
     SELECT ... 
     LOOP 
     RETURN NEXT ...; 
     END LOOP; 
     ... 
    END LOOP; 
END; 
関連する問題