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

从通用表表达式中INSERT中使用的子选择返回数据

徐鑫鹏
2023-03-14

我尝试将< code>bytea数据从一个表移动到另一个表,在一个查询中更新引用。

因此,我想从用于插入的查询中返回不用于插入的数据。

INSERT INTO file_data (data)
  select image from task_log where image is not null
RETURNING id as file_data_id, task_log.id as task_log_id

但我得到了一个查询错误:

[42P01] ERROR: missing FROM-clause entry for table "task_log"

我想做这样的事情:

WITH inserted AS (
  INSERT INTO file_data (data)
    SELECT image FROM task_log WHERE image IS NOT NULL
  RETURNING id AS file_data_id, task_log.id AS task_log_id
)
UPDATE task_log
SET    task_log.attachment_id = inserted.file_data_id,
       task_log.attachment_type = 'INLINE_IMAGE'
FROM   inserted
WHERE  inserted.task_log_id = task_log.id;

但我无法获取用于插入的所有数据,我无法从子选择返回id。

我受到这个关于如何使用通用表表达式做到这一点的答案的启发,但我找不到一种方法来使它工作。

共有2个答案

屠泰平
2023-03-14

我需要复制副本,所以我最后添加了一个temp列作为所用数据行的id。

alter table file_data add column task_log_id bigint;
-- insert & update data
alter table file_data drop column task_log_id;

完整的移动脚本是

-- A new table for any file data
CREATE TABLE file_data (
  id         BIGSERIAL PRIMARY KEY,
  data  bytea
);

-- Move data from task_log to bytes

-- Create new columns to reference file_data
alter table task_log add column attachment_type VARCHAR(50);
alter table task_log add column attachment_id bigint REFERENCES file_data;

-- add a temp column for the task_id used for the insert
alter table file_data add column task_log_id bigint;

-- insert data into file_data and set references
with inserted as (
  INSERT INTO file_data (data, task_log_id)
    select image, id from task_log where image is not null
  RETURNING id, task_log_id
)
UPDATE task_log
SET   attachment_id = inserted.id,
      attachment_type = 'INLINE_IMAGE'
FROM  inserted
where inserted.task_log_id = task_log.id;
-- delete the temp column
alter table file_data drop column task_log_id;
-- delete task_log images
alter table task_log drop column image;

由于这会产生一些死数据,我事后运行了一个真空机进行清理。

但请让我重复@ErwinBrandstetter的警告:

性能比我在链接答案中提出的使用序列号的方法差得多。添加

巫马越彬
2023-03-14

您需要正确设置表名和别名。另外,两个表之间的连接是列image(新表中的datafile_data):

WITH inserted AS (
  INSERT INTO file_data (data)
  SELECT image
  FROM   task_log
  WHERE  image IS NOT NULL
  RETURNING id, data  -- can only reference target row
)
UPDATE task_log t
SET    attachment_id = i.id
     , attachment_type = 'INLINE_IMAGE'
FROM   inserted i
WHERE  t.image = i.data;

就像我在你提到的旧答案中解释的那样,< code>image在< code>task_log中必须是唯一的,这样才能起作用:

    < li >使用Postgres插入数据并设置外键

我添加了一种技术,如何消除引用答案中非唯一值的歧义。但是,不确定您是否希望file_data中出现重复的图像。

INSERTRETURNING子句中,只能引用插入行中的列。手册:

可选的< code > return 子句使< code>INSERT根据实际插入的每一行计算并返回值(...)但是,任何使用表列的表达式都是允许的。

大胆强调我的。

如果要在 INSERTtask_log)的目标表中使用不同的条目,则在这种情况下,您只需要在初始 SELECT显示 DISTINCT

WITH inserted AS (
  INSERT INTO file_data (data)
  SELECT DISTINCT image  -- fold duplicates
  FROM   task_log
  WHERE  image IS NOT NULL
  RETURNING id, data  -- can only reference target row
)
UPDATE task_log t
SET    attachment_id = i.id
     , attachment_type = 'INLINE_IMAGE'
FROM   inserted i
WHERE  t.image = i.data;

生成的 file_data.idtask_log中多次使用。请注意,task_log中的多行现在指向file_data中的同图像。小心更新和删除...

 类似资料:
  • 我希望能够连续轮询数据库,使用Camel从我的表中选择数据。我已经在我的spring boot应用程序中配置了Camel。以下是我正在使用的配置 建筑格拉德尔: RouteBuilder类: 豆: application.properties 我面临的问题是,当我打印bean方法参数(generateSalesData(String payload))时,我得到的是查询字符串本身(“从投标书中选择

  • 我有两个对象,其签名如下:

  • 问题内容: 我在python大熊猫中有一个数据框。数据框的结构如下: 我想选择以d开头的列。有没有一种简单的方法可以在python中实现。 问题答案: 您可以使用这种方式: 这个想法是通过选择列

  • 我想从表1中选择不在表2中的数据,但我必须从表1中选择特定的数据 我的数据表 我想做什么 选择名称,id从表1其中id!=(从表2选择table1_id加入表3table2.acc_id=table3.acc_id其中table2.did=4759505和table2.acc_id=2)table1.acc_id=2 如果子查询返回一行,上面的查询工作正常,但如果子查询返回多行,则不正常 谢谢

  • 问题内容: 如果我有类似“ something12”或“ something102”的字符串,我将如何在javascript中使用正则表达式来仅返回数字部分? 问题答案: 常用表达: 这将返回一个内部带有两个元素“ 102”和“ 1948948”的对象。随心所欲地操作。如果不匹配,则返回null。 串联它们: 假设您不处理复杂的小数,我想这就足够了。