PostgresQL-为SELECT查询定义序列

PostgresQL-为SELECT查询定义序列,sql,database,postgresql,sequence,Sql,Database,Postgresql,Sequence,我有一个视图,我使用某个SELECT语句,其中有一个CASE条件,根据某个条件为真或假来决定是增加计数器还是使用当前值 据我所知,SELECT语句的任何视图在每次引用时都会生成,因此每次引用时我都想重新创建序列 例如: CREATE TABLE num( n BIGINT PRIMARY KEY ); INSERT INTO num(n) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9); CREATE TEMP SEQUENCE seq

我有一个
视图
,我使用某个
SELECT
语句,其中有一个
CASE
条件,根据某个条件为真或假来决定是增加计数器还是使用当前值

据我所知,
SELECT
语句的任何视图在每次引用时都会生成,因此每次引用时我都想重新创建
序列

例如:

CREATE TABLE num(
n BIGINT PRIMARY KEY
);

INSERT INTO num(n) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9);

CREATE TEMP SEQUENCE seq START 1;
SELECT nextval('seq');

SELECT 
CASE WHEN n % 2 = 0 THEN nextval('seq')
     ELSE currval('seq')
END AS test,
n
FROM num;
我必须在
SELECT
语句之前插入
selectnextval('seq')
,否则它会产生错误

ERROR:  currval of sequence "seq" is not yet defined in this session
在一天结束时,该代码不会每次重新创建
序列,因为它只会使用创建的序列生成新值

这段代码按预期工作,但从我的角度看,闻起来像糟糕的数据库设计


你们中有谁知道,每次调用
SELECT
时,如何创建一个新的
SEQUENCE
对象?还是有别的办法?我觉得应该有一个干净清晰的方法来做到这一点,我肯定错过了一些东西

对于您的示例,您可以在
选择中设置序列的值:

SELECT (CASE WHEN n % 2 = 0 THEN nextval('seq')
             ELSE currval('seq')
        END) AS test,
       n
FROM num CROSS JOIN
     (SELECT setval('seq', 1)) s;
在外部
SELECT
之前,应该先计算
FROM
子句,因此外部
SELECT
应该从指定的值开始

他是一把小提琴

我应该注意到,这确实表明数据库设计存在问题。然而,我可以想象一个视图包含:

FROM (SELECT NEXT_VALUE('view_cnt')) x CROSS JOIN
     . . .

计算调用视图的次数。这可能是一个方便的信息。

根据使用方法,视图中的每一行都会有一个增量,而不是每个视图一次。@GordonLinoff我试图更好地解释,并提供了一个最小的工作示例。请检查更新。交叉连接不需要太多操作吗?因为从外观上看,它将集合A的每个值映射到集合B的每个值。既然B(序列)实际上是无限的,这怎么可能呢?@winwin。你误解了密码。子查询执行一次(因为它位于
FROM
子句中)。它返回一行。然后,该行与查询的其余部分“交叉连接”。但是,除了使刚刚计算的列可用之外,它没有做什么。但因为没有使用,它实际上没有任何效果。