2015-11-03 50 views
0

我試圖通過一組預先定義的整數來獲得查詢循環:環流式SQL查詢 - PostgreSQL的

我做了查詢這個問題很簡單。這是僞代碼很明顯!

my_id = 0 
WHILE my_id < 10 
    SELECT * from table where id = :my_id` 
    my_id += 1 
END 

我知道,這個查詢我可以做這樣的事情其中id < 10 ..但我執行實際的查詢是大約60線長,不少窗口語句都指的是有問題的變量。

它的工作原理,並得到我想要的結果,當我有變量設置爲一個單一的數字..我只需要能夠重新運行查詢10次與不同的變量,希望結束了一個單一的集的結果。

到目前爲止,我有這樣的:

CREATE OR REPLACE FUNCTION stay_prices (a_product_id int) RETURNS TABLE (
    pid int, 
    pp_price int 
) AS $$ 
DECLARE 
    nights int; 
    nights_arr INT[] := ARRAY[1,2,3,4]; 
    j int; 
BEGIN 
    j := 1; 
    FOREACH nights IN ARRAY nights_arr LOOP 

    -- query here.. 

    END LOOP; 
    RETURN; 
END; 
$$ LANGUAGE plpgsql; 

但我得到這個回:

ERROR: query has no destination for result data 
HINT: If you want to discard the results of a SELECT, use PERFORM instead. 

所以我需要讓我的查詢SELECT ... INTO返回表不知何故?或者還有什麼我可以做的嗎?

編輯:這是我在運行實際查詢的例子:

\x auto 
\set nights 7 

WITH x AS (
    SELECT 
     product_id, night, 
     LAG(night, (:nights - 1)) OVER (
      PARTITION BY product_id 
      ORDER BY night 
     ) AS night_start, 
     SUM(price_pp_gbp) OVER (
      PARTITION BY product_id 
      ORDER BY night 
      ROWS BETWEEN (:nights - 1) PRECEDING 
      AND CURRENT ROW 
     ) AS pp_price, 
     MIN(spaces_available) OVER (
      PARTITION BY product_id 
      ORDER BY night 
      ROWS BETWEEN (:nights - 1) PRECEDING 
      AND CURRENT ROW 
     ) AS min_spaces_available, 
     MIN(period_date_from) OVER (
      PARTITION BY product_id 
      ORDER BY night 
      ROWS BETWEEN (:nights - 1) PRECEDING 
      AND CURRENT ROW 
     ) AS min_period_date_from, 
     MAX(period_date_to) OVER (
      PARTITION BY product_id 
      ORDER BY night 
      ROWS BETWEEN (:nights - 1) PRECEDING 
      AND CURRENT ROW 
     ) AS max_period_date_to 

    FROM products_nightlypriceperiod pnpp 
    WHERE 
     spaces_available >= 1 
     AND min_group_size <= 1 
     AND night >= '2016-01-01'::date 
     AND night <= '2017-01-01'::date 
) 
SELECT 
    product_id as pid, 
    CASE WHEN x.pp_price > 0 THEN x.pp_price::int ELSE null END as pp_price, 
    night_start as from_date, 
    night as to_date, 
    (night-night_start)+1 as duration, 
    min_spaces_available as spaces 
FROM x 
WHERE 
    night_start = night - (:nights - 1) 
    AND min_period_date_from = night_start 
    AND max_period_date_to = night; 

這將讓我所有支持我的所有產品在2016年nights夜間時間段的價格期間沿和我可以填寫的最大空間數量。

我希望能夠運行此查詢,以獲得所有我的產品在2到30天之間的所有期間。

這很可能會產生一個包含數百萬行的表格。計劃是定期重新創建此表,以便快速查看特定日期的可用內容。 products_nightlypriceperiod表示產品可用性的夜晚 - 例如, Product X has 3 spaces left for Jan 1st 2016, and costs £100 for the night

+0

把數字列表放在(temp)表中,你不需要循環。 – joop

+1

或者使用一個具有所需數字的CTE:'用the_values(my_id)作爲(值(1),(2),(3))...'並加入反對。或者,如果數字總是連續的,請使用'generate_series()' –

回答

2

爲什麼使用循環?你可以做這樣的事情(使用你的第一個查詢):

with params as (
     select generate_series(1, 10) as id 
    ) 
select t.* 
from params cross join 
    table t 
where t.id = params.id; 

可以修改params有你真正想要的值。然後,只需使用cross join並讓數據庫「執行循環」。

+0

沒有看到..謝謝。將看看它 - 我有的sql語句在它有一個子查詢 - 並且子查詢和主查詢都使用相同的變量。我將把一個編輯過的版本放入問題中,因爲這會使事情複雜化。 –

+0

@GuyBowden。 。 。將'params'放入子查詢中,然後向外傳播值。 –

+0

這很好,直到您需要使用LAG或ROW語句中的參數。我將用示例查詢編輯我的問題。 –