2013-06-24 30 views
12

Tôi muốn sử dụng chức năng tạo chuỗi trong chuyển đổi màu đỏ, nhưng chưa thành công.Sử dụng hàm generate_series sql() trong redshift

Tài liệu hướng dẫn lại cho biết nó không được hỗ trợ. Các mã sau đây làm việc:

select * 
from generate_series(1,10,1) 

kết quả đầu ra:

1 
2 
3 
... 
10 

Tôi muốn làm điều tương tự với quả chà là. Tôi đã thử một số biến thể, bao gồm:

select * 
from generate_series(date('2008-10-01'),date('2008-10-10 00:00:00'),1) 

đá ra:

ERROR: function generate_series(date, date, integer) does not exist 
Hint: No function matches the given name and argument types. 
You may need to add explicit type casts. [SQL State=42883] 

Cũng thử:

select * 
from generate_series('2008-10-01 00:00:00'::timestamp, 
'2008-10-10 00:00:00'::timestamp,'1 day') 

Và thử:

select * 
from generate_series(cast('2008-10-01 00:00:00' as datetime), 
cast('2008-10-10 00:00:00' as datetime),'1 day') 

cả đá ra:

ERROR: function generate_series(timestamp without time zone, timestamp without time zone, "unknown") does not exist 
Hint: No function matches the given name and argument types. 
You may need to add explicit type casts. [SQL State=42883] 

Nếu không trông giống như tôi sẽ sử dụng mã này từ bài khác:

SELECT to_char(DATE '2008-01-01' 
+ (interval '1 month' * generate_series(0,57)), 'YYYY-MM-DD') AS ym 

PostgreSQL generate_series() with SQL function as arguments

+2

Chạy 'phiên bản SELECT()' đối với cơ sở dữ liệu của bạn để truy xuất phiên bản Postgres của bạn. –

+0

Để biết cách giải quyết khác, hãy xem: http://stackoverflow.com/a/34167753/3019685 – systemjack

+0

Tôi đã đăng giải pháp thay thế trong một câu hỏi tương tự tại đây https://stackoverflow.com/questions/22759980/generate-series-method-fails- in-redshift – AlexYes

Trả lời

15

Amazon Redshift seems to be based on PostgreSQL 8.0.2. Các đối số dấu thời gian để generate_series() được thêm vào 8.4.

Một cái gì đó như thế này, điều này gây khó chịu cho vấn đề đó, có thể hoạt động trong tính năng Redshift.

SELECT current_date + (n || ' days')::interval 
from generate_series (1, 30) n 

Nó hoạt động trong PostgreSQL 8.3, đây là phiên bản đầu tiên tôi có thể kiểm tra. Nó được ghi lại trong 8.0.26.

Sau đó. . .

Có vẻ như là generate_series() is unsupported trong Redshift. Nhưng nếu bạn đã xác minh rằng select * from generate_series(1,10,1)thì hoạt động, cú pháp ở trên ít nhất sẽ mang đến cho bạn cơ hội chiến đấu. (Mặc dù kiểu dữ liệu khoảng thời gian cũng được ghi nhận là không được hỗ trợ trên Redshift.)

Sau đó. . .

Bạn cũng có thể tạo một bảng các số nguyên.

create table integers (
    n integer primary key 
); 

Tuy nhiên, hãy điền nó theo ý bạn. Bạn có thể sử dụng generate_series() cục bộ, đổ bảng và tải nó lên Redshift. (Tôi không biết, tôi không sử dụng Redshift.)

Dù sao, bạn có thể thực hiện phép tính số học đơn giản với bảng đó mà không tham chiếu trực tiếp đến generate_series() hoặc các kiểu dữ liệu khoảng.

select (current_date + n) 
from integers 
where n < 31; 

Điều đó hoạt động trong 8.3, ít nhất.

+3

+1 Điều đó dường như giải thích nó. Ít hơn ấn tượng từ amazon ... –

4

Chức năng generate_series() không được Redshift hỗ trợ đầy đủ. Xem phần Unsupported PostgreSQL functions của hướng dẫn dành cho nhà phát triển.

7

Sử dụng tính năng Chuyển đổi ngày hôm nay, bạn có thể tạo phạm vi ngày bằng cách sử dụng các hàm ngày giờ và cho ăn trong bảng số.

select (getdate()::date - generate_series)::date from generate_series(1,30,1) 

Tạo điều này cho tôi

date 
2015-11-06 
2015-11-05 
2015-11-04 
2015-11-03 
2015-11-02 
2015-11-01 
2015-10-31 
2015-10-30 
2015-10-29 
2015-10-28 
2015-10-27 
2015-10-26 
2015-10-25 
2015-10-24 
2015-10-23 
2015-10-22 
2015-10-21 
2015-10-20 
2015-10-19 
2015-10-18 
2015-10-17 
2015-10-16 
2015-10-15 
2015-10-14 
2015-10-13 
2015-10-12 
2015-10-11 
2015-10-10 
2015-10-09 
2015-10-08 
+2

trong khi điều này tạo ra một loạt, tôi đã tìm thấy không có cách nào (CTE, truy vấn phụ, hoặc chèn vào một bảng hoặc bảng tạm thời để nối nó với một bảng khác để lọc). – cfeduke

+1

@cfeduke bạn có thể bọc nó vào bảng tạm thời bằng '' 'với chuỗi AS ( chọn * từ generate_series (1,10,1) ) chọn * từ chuỗi''' – blotto

+1

@blotto - cảm ơn bạn! Nhận xét của bạn và ví dụ cuối cùng trong câu hỏi đã giải quyết được vấn đề cho tôi. – GeekyDeaks

0

tôi cần phải làm điều gì đó tương tự, nhưng với 5 phút khoảng hơn 7 ngày. Vì vậy, đây là một CTE dựa hack (xấu xí nhưng không quá tiết)

INSERT INTO five_min_periods 
WITH 
periods AS (select 0 as num UNION 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 10 UNION select 11), 
hours AS (select num from periods UNION ALL select num + 12 from periods), 
days  AS (select num from periods where num <= 6), 
rightnow AS (select CAST(TO_CHAR(GETDATE(), 'yyyy-mm-dd hh24') || ':' || trim(TO_CHAR((ROUND((DATEPART (MINUTE, GETDATE())/5), 1) * 5),'09')) AS TIMESTAMP) as start) 
select 
    ROW_NUMBER() OVER(ORDER BY d.num DESC, h.num DESC, p.num DESC) as idx 
    , DATEADD(minutes, -p.num * 5, DATEADD(hours, -h.num, DATEADD(days, -d.num, n.start))) AS period_date 
from days d, hours h, periods p, rightnow n 

Nên có thể mở rộng này sang các chương trình thế hệ khác. Bí quyết ở đây là sử dụng tham gia sản phẩm Descartes (tức là không có mệnh đề JOIN/WHERE) để nhân CTE được tạo thủ công để tạo ra các gia số cần thiết và áp dụng cho một ngày neo.

Các vấn đề liên quan