当前位置: 首页 > 知识库问答 >
问题:

postgres,使用另一个表中的数据批量更新

巢海
2023-03-14

我有一个目标表(已经填充了数据)和另一个(源表),我需要将数据检索到第一个。

目标_表格

postgres=# select id,id_user from ttasks;
 id | id_user
----+---------
  1 |
  2 |
  3 |
  4 |
  5 |
(5 rows)

source_table

postgres=# select id from tusers where active;
  id
------
 1011
 1012
 1013
 1014
(4 rows)

我需要使用 tusers 表中的 id 更新 ttasks 表id_user列,因此 ttasks 的最终结果应该是:

# expected result after update [select id, id_user from ttasks;]
 id | id_user
----+---------
  1 |    1011
  2 |    1012
  3 |    1013
  4 |    1014
  5 |    1011
(5 rows)

我尝试过的(类似于INSERT… from…语句):

postgres=# update ttasks t1 set id_user = q1.id from (select id from tusers where active) q1 returning t1.id,t1.id_user;
 id | id_user
----+---------
  1 |    1011  
  2 |    1011
  3 |    1011
  4 |    1011  
  5 |    1011  
(5 rows)

但是这个查询总是使用我的q1子查询中的第一个id。

关于我如何完成这项任务,有什么想法、帮助甚至解决方案吗?非常感谢!

p、 这是我在这个社区的第一篇帖子,所以如果我的问题不符合你的规则,请对我温柔一点。

共有1个答案

苏浩瀚
2023-03-14

最后,在我的一个朋友告诉我,并不是所有的东西都可以用“保持愚蠢的简单”的方式进行编码之后,我编写了一个plpqsql(PL/PGSQL)函数,它为我完成了这项工作,并且允许在内部使用一些高级过滤器。

CREATE OR REPLACE FUNCTION assign_workers_to_tasks(i_workers_table regclass, i_workers_table_tc text, i_tasks_table regclass, i_tasks_table_tc text, i_workers_filter text DEFAULT ''::text, i_tasks_filter text DEFAULT ''::text)
  RETURNS void AS
$BODY$
  DECLARE workers int[]; i integer; total_workers integer; r record; get_tasks text;
begin
    i_workers_filter := 'where '||nullif(i_workers_filter,'');
    i_tasks_filter := 'where '||nullif(i_tasks_filter,'');
    EXECUTE format('select array_agg(%s) from (select %s from %s %s order by %s) q', i_workers_table_tc, i_workers_table_tc,i_workers_table, i_workers_filter,i_workers_table_tc)
    INTO workers; --available [filtered] workers
    total_workers := coalesce(array_length(workers,1),0); --total of available [filtered] workers
    IF total_workers = 0 THEN
      EXECUTE format('update %s set %s=null %s', i_tasks_table, i_tasks_table_tc, i_tasks_filter);
      RETURN;
    END IF;
    i :=1;
    get_tasks := format('select * from %s %s',i_tasks_table,i_tasks_filter); --[filtered] tasks
    FOR r IN EXECUTE (get_tasks) LOOP
      EXECUTE format('update %s set %s=%s where id = %s', i_tasks_table, i_tasks_table_tc, workers[i],r.id);
      i := i+1;
      IF i>total_workers THEN i := 1; END IF;
    END LOOP;
    RETURN;
end;
  $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION assign_workers_to_tasks(regclass, text, regclass, text, text, text)
  OWNER TO postgres;

为了回答我自己的问题:

select assign_workers_to_tasks('tusers','id','ttasks','id_user','active');
 类似资料:
  • 问题内容: 表格1: 表2: 在oracle SQL中,如何运行 sql更新 查询,该查询可以使用表2并使用表2来更新表1 ?所以我得到的最终结果是 表格1: 问题答案: 这称为相关更新 假设联接导致键保留视图,您还可以

  • 问题内容: 我在SQLite中有两个表,看起来像这样 我试图编写查询以基于表Y中的记录更新表X上的记录。更新的条件如下所示 但是当我尝试这样做时,我收到一条错误消息,说 没有这样的列:table_y.c2 问题答案: 删除的答案关于错误的原因是正确的:必须在查询中 引入 关系标识符(例如,使用FROM / JOIN),然后才能使用它。 虽然SQLite的不 不 支持(因此没有办法直接引入查找关系)

  • 问题内容: 是否可以在带有子选择的mysql 5.0上运行UPDATE命令。 我要运行的命令是这样的: ISBN13当前存储为字符串。 这应该更新10k +行。 谢谢, 威廉 问题答案: 只需更改一下即可:

  • 问题内容: 我有一张桌子,看起来像这样 我正在寻找一种方法,以使用“ VALUE”列中其他行中具有相同“ NAME”的数据更新值“ Test2”和“ Test”(此处ID并非唯一,ID的复合键和NAME成为唯一的一行)。例如,我正在寻找的输出是: 如果在另一个表中,我会没事的,但是我对于如何使用相同的NAME值引用当前表中的另一行感到困惑。 更新资料 修改完manji查询后,下面是我用于有效解决方

  • 问题内容: 有什么方法可以简化为一个查询吗? 问题答案: 是的,您可以使用以下查询进行操作:

  • 问题内容: 我试图用另一个表中找到的值更新一个表中的所有记录。 我尝试了相同基本查询的许多版本,并且始终收到相同的错误消息: 操作必须使用可更新的查询。 关于为什么此查询在Access DB中不起作用的任何想法? 也尝试了此操作,因为我意识到第二张表的每个型号都有多个型号记录-我只需要为每个型号找到第一条记录中的第一条说明。 …虽然仍然出现相同的错误。 问题答案: 您必须使用联接