转置生成系列日期postgresql

Transpose generate series date postgresql

之前有很多次询问有关转置的问题,但在使用generate_series和date时我找不到任何好的答案,因为列可能会有所不同。

1
2
3
WITH range AS
(SELECT to_char(generate_series('2015-01-01','2015-01-05', INTERVAL '1 day'),'YYYY-MM-DD'))
SELECT * FROM range;

generate系列的正常输出是:

1
2
3
4
2015-12-01
2015-12-02
2015-12-03
... AND so ON

http://sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/5478

但我希望它成为专栏

1
2015-12-01  2015-12-02  2015-12-03  ...and so ON

似乎交叉表可能应该做的伎俩,但我只会得到错误:

1
2
SELECT * FROM crosstab('(SELECT to_char(generate_series('2015-01-01','2015-01-05', interval '1 DAY'),'YYYY-MM-DD'))')
AS ct (dynamic COLUMNS?)

如何让交叉表与generate_series(日期 - 日期)和动态的不同间隔一起使用?

TIA


从链接PostgreSQL查询引用参考生成的列。

您可以动态生成列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE OR REPLACE FUNCTION sp_test()
RETURNS void AS
$$

DECLARE cases CHARACTER VARYING;
DECLARE sql_statement text;
BEGIN
    DROP TABLE IF EXISTS temp_series;
    CREATE TEMPORARY  TABLE temp_series AS
    SELECT to_char(generate_series('2015-01-01','2015-01-02', INTERVAL '1 day'),'YYYY-MM-DD') AS series;

    SELECT string_agg(concat('max(case when t1.series=','''',series,'''',' then t1.series else ''0000-00-00'' end) as ','"', series,'"'),',') INTO cases FROM temp_series;

    DROP TABLE IF EXISTS temp_data;
    sql_statement=concat('create temporary table temp_data as select ',cases ,'
    from temp_series t1'
);

    raise notice '%',sql_statement;
    EXECUTE sql_statement;
END;
$$
LANGUAGE 'plpgsql';

以下列方式调用函数来获取输出:

1
SELECT sp_test(); SELECT * FROM temp_data;

更新的函数,需要两个日期参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE OR REPLACE FUNCTION sp_test(start_date TIMESTAMP WITHOUT TIME zone,end_date TIMESTAMP WITHOUT TIME zone)
RETURNS void AS
$$

DECLARE cases CHARACTER VARYING;
DECLARE sql_statement text;
BEGIN
    DROP TABLE IF EXISTS temp_series;
    CREATE TEMPORARY  TABLE temp_series AS
    SELECT to_char(generate_series(start_date,end_date, INTERVAL '1 day'),'YYYY-MM-DD') AS series;

    SELECT string_agg(concat('max(case when t1.series=','''',series,'''',' then t1.series else ''0000-00-00'' end) as ','"', series,'"'),',') INTO cases FROM temp_series;

    DROP TABLE IF EXISTS temp_data;
    sql_statement=concat('create temporary table temp_data as select ',cases ,'
    from temp_series t1'
);

    raise notice '%',sql_statement;
    EXECUTE sql_statement;
END;
$$
LANGUAGE 'plpgsql';

功能调用:

1
SELECT sp_test('2015-01-01','2015-01-10'); SELECT * FROM temp_data;