Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL:选择字段值并使用第二个表中的下一个值进行更新_Sql_Postgresql - Fatal编程技术网

PostgreSQL:选择字段值并使用第二个表中的下一个值进行更新

PostgreSQL:选择字段值并使用第二个表中的下一个值进行更新,sql,postgresql,Sql,Postgresql,使用上述表格,我想从t_b中选择a_id_fk,其中b_id=1,然后用序列中的下一个a_id更新a_id_fk,但如果我在可用的a_id的末尾,我会循环回到第一个。所有这些都需要多人从t\u b查询/更新特定行 如果有帮助的话,我正在研究的场景是,多个站点共享一个共同的单词列表,但是当每个站点的每个用户抓取一个单词时,单词列表中的站点索引将移动到下一个单词,直到它到达末尾,然后循环回到开头 有没有一种方法可以在单个查询中实现这一点?如果没有,处理这个问题的最佳方法是什么?我可以处理大部分逻辑,

使用上述表格,我想
从t_b中选择a_id_fk,其中b_id=1
,然后用序列中的下一个
a_id
更新a_id_fk,但如果我在可用的
a_id
的末尾,我会循环回到第一个。所有这些都需要多人从
t\u b
查询/更新特定行

如果有帮助的话,我正在研究的场景是,多个站点共享一个共同的单词列表,但是当每个站点的每个用户抓取一个单词时,单词列表中的站点索引将移动到下一个单词,直到它到达末尾,然后循环回到开头


有没有一种方法可以在单个查询中实现这一点?如果没有,处理这个问题的最佳方法是什么?我可以处理大部分逻辑,当我用完ID时,它会循环返回,这让我感到困惑。

你可以使用一些复杂的东西,比如

CREATE TABLE t_a
(
  a_id SERIAL PRIMARY KEY,
  str VARCHAR(50)
)

CREATE TABLE t_b
(
  b_id SERIAL PRIMARY KEY,
  a_id_fk INTEGER REFERENCES (t_a(a_id),
)

但是如果给我一个这样的要求,我可能会维护一个辅助表,将一个a_id映射到循环中的下一个a_id…

这个比@pdw的解决方案更优雅(IMHO):

UPDATE t_b
    SET a_id_fk = COALESCE(
        (SELECT MIN(a_id) FROM t_a WHERE a_id > t_b.a_id_fk),
        (SELECT MIN(a_id) FROM t_a))
    WHERE b_id = :b_id

结果:

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE t_a
( a_id SERIAL PRIMARY KEY
, str VARCHAR(50)
);

CREATE TABLE t_b
( b_id SERIAL PRIMARY KEY
, a_id_fk INTEGER REFERENCES t_a(a_id)
);

INSERT INTO t_a(str)
SELECT 'Str_' || gs::text
FROM generate_series(1,10) gs
        ;
INSERT into t_b(a_id_fk)
SELECT a_id FROM t_a
ORDER BY a_id
        ;

-- EXPLAIN ANALYZE
WITH src AS (
        SELECT a_id AS a_id
        , min(a_id) OVER (order BY a_id) AS frst
        , lead(a_id) OVER (order BY a_id) AS nxt
        FROM t_a
        )
UPDATE t_b dst
SET a_id_fk = COALESCE(src.nxt, src.frst)
FROM src
WHERE dst.a_id_fk = src.a_id
AND dst.b_id IN ( 3, 10)
        ;

SELECT * FROM t_b
ORDER BY b_id
        ;

那很好。祝你好运。你有问题吗?你想更新t_b.a_id_fk吗?新值应该是什么?新值将是下一个t_a.a_id,当按a_id排序时,除非没有,否则它将从开头开始。从头开始并不容易。我从未想过在联合中使用查询,但我想这会奏效。我如何构造一个辅助表来处理这个问题,它是否能够为
tub
中的每个条目维护一个单独的索引?
DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
CREATE TABLE
INSERT 0 10
INSERT 0 10
UPDATE 2
 b_id | a_id_fk 
------+---------
    1 |       1
    2 |       2
    3 |       4
    4 |       4
    5 |       5
    6 |       6
    7 |       7
    8 |       8
    9 |       9
   10 |       1
(10 rows)