在case case中使用generate_series的问题

时间:2017-12-14 19:31:28

标签: postgresql case generate-series

最近,我的团队已将postgres服务器的版本从9.3更新到10.1

我们的一个程序有一段代码,现在正在给我们一些问题。这只是原始代码的一个示例:

        SELECT 
            CASE 
                WHEN current_date = '2017-12-14'    THEN generate_series(current_date , '2017-12-31'::DATE , '1 day') 
                WHEN current_date = '2017-12-15'    THEN generate_series(current_date , '2017-12-31'::DATE , '1 day') 
                ELSE generate_series('2017-12-01'::DATE, '2017-12-31'::DATE, '1 day') 
             END AS workday

如果我在之前的服务器中运行此代码,我就得到了序列。但是在postgres 10.1中我收到此错误消息:

“CASE中不允许使用set-returns函数。”

这个版本的postgres有什么问题这是一个错误,还是有另一种方法来获得预期的结果

2 个答案:

答案 0 :(得分:1)

您需要将set-returns函数移出CASE语句,以便它一次只返回一行。我会通过使CASE成为您使用结果列的子查询来简化您的声明:

SELECT generate_series(series_start_date::DATE, '2017-12-31'::DATE, '1 day') FROM 
    (
        SELECT
            CASE
                WHEN current_date='2017-12-14' THEN current_date
                WHEN current_date='2017-12-15' THEN current_date
                ELSE '2017-12-01'
            END AS series_start_date
    ) as temp_alias;

该查询应该可以提供您想要的内容。

放置&tempaalias'在那里是必需的,但没有使用。

免责声明:我在Postgres 9.6上测试了这个,这是我现在可以测试的全部内容。它应该与Postgres 10.1一起使用。

答案 1 :(得分:0)

在标量上下文中使用set-returns函数是一种破解。他们完全被Andres Freund重写为更好的实现。

发行说明:Change the implementation of set-returning functions appearing in a query's SELECT list (Andres Freund)

作为一种替代方法,您可以使用import pyodbc conn = pyodbc.connect('DRIVER={FreeTDS};DSN=MYMSSQL;UID=<>;PWD=<>') crsr = conn.cursor() rows = crsr.execute("SELECT * FROM transaction_detail_check").fetchall() print(rows) crsr.close() conn.close() 将确定参考日期的逻辑加入LATERAL JOIN

generate_series

SQL小提琴here