2014-03-31 44 views
5

失敗當我運行SQL查詢:generate_series()方法紅移

select generate_series(0,g) 
from (select date(date1) - date(date2) as g from mytable ; 

它返回一個錯誤:

INFO: Function "generate_series(integer,integer)" not supported. 
ERROR: Specified types or functions (one per INFO message) not supported 
on Redshift tables. 

但是當我運行此查詢:

select generate_series(0, g) from (select 5 as g) 

它返回以下響應:

generate_series 
----------------- 
0 
1 
2 
3 
4 
5 
(6 rows) 

爲什麼第二個查詢可以工作,而第一個查詢失敗?

+0

顯然,第一子查詢返回的'interval'不是'integer'(因爲:「* generate_series(整數區間)不存在*」) –

+0

在錯誤消息中看到我的編輯。 – DJo

+3

您沒有使用PostgreSQL。您正在使用Amazon Redshift。 –

回答

0

您沒有使用PostgreSQL。您正在使用Amazon Redshift。

與Redshift表一起使用時,Amazon Redshift不支持generate_series。它在錯誤信息中就是這樣說的。

要麼使用真正的PostgreSQL,要麼需要Redshift的功能,還必須在Redshift的限制範圍內工作。

你的第二個例子工作,因爲它不使用任何Redshift表

+0

這不是一個領導者節點只支持的功能嗎? – Naveen

+0

@Naveen也許這是現在,但不是當我寫這個。 –

1

這可以在這裏使用(pg-9.3.3)也許你的問題只是Redshift-「功能」的結果?

CREATE TABLE mytable 
     (date1 timestamp 
     , date2 timestamp 
     ); 
INSERT INTO mytable(date1,date2) VALUES 
('2014-03-30 12:00:00' , '2014-04-01 12:00:00'); 

SELECT generate_series(0, ss.g) FROM 
    (SELECT date(date2) - date(date1) AS g 
    FROM mytable 
    ) ss ; 
12

generate_series()函數不完全支持Redshift。請參閱開發人員指南的Unsupported PostgreSQL functions部分:

在具體示例中,第二個查詢完全在Leader節點上執行,因爲它不需要掃描任何實際的表數據,而第一個查詢嘗試選擇數據,這將在計算節點上執行。

5

您可以使用window function獲得類似的結果。這需要一個現有的表(如stv_blocklist)播種,至少有你需要的行數,但不會太多,這可能會減慢速度。

with days as (
    select (dateadd(day, -row_number() over (order by true), sysdate::date)) as day 
    from [other_existing_table] limit 30 
) 
select day from days order by 1 asc 

您可以使用此方法獲取其他時間範圍以及出於分包目的。該版本可生成前一天的所有分鐘數據,因此您可以對其進行左連接並存儲數據。

with buckets AS (
    select (dateadd(minute, -row_number() over (order by true), sysdate::date)) as minute 
    from [other_table] limit 1440 
) 
select minute from buckets order by 1 asc 

我可能第一次看到這個here

0

上面解釋了爲什麼它不起作用。不過,這個問題「我們能做些什麼呢?」開了。

如果您在任何平臺(無論是否支持生成器)上開發BI系統,那麼使用包含數字和日期序列的維度表非常方便。你如何在Redshift中創建一個?

  1. Postgres裏,使用發電機
  2. 出口到CSV
  3. 產生必要的序列創建一個表與在紅移同一模式
  4. 導入CSV從步驟2到紅移

想象一下,你已經創建了一個非常簡單的表,名爲calendar

id, date 
1, 2017-01-01 
2, 2017-01-02 
..., ... 
xxx, 2020-01-01 

所以你的查詢將是這樣的:

SELECT t.id, t.date_1, t.date_2, c.id as date_id, c.date 
FROM mytable t 
JOIN calendar c 
ON c.date BETWEEN t.date_1::date AND t.date_2::date 
ORDER BY 1,4 

在日曆表,你也可以擁有的周,月,季,平日第一時間(週一,週二,等等),這使得這樣的表超有效用於基於時間的聚合。

1

你是對的,這在Redshift上不起作用。 請參閱here

你可以使用類似這樣

with ten_numbers as (select 1 as num union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) 
,generted_numbers AS 
(
    SELECT (1000*t1.num) + (100*t2.num) + (10*t3.num) + t4.num-5000 as gen_num 
    FROM ten_numbers AS t1 
     JOIN ten_numbers AS t2 ON 1 = 1 
     JOIN ten_numbers AS t3 ON 1 = 1 
     JOIN ten_numbers AS t4 ON 1 = 1 
) 
select gen_num from generted_numbers 
where gen_num between -10 and 0 
order by 1;