如何添加到 table 然后将 id 用于不同的查询?

How do I add to a table and then use the id for a different query?

我有三个 tables,我用这些查询创建的:

create table parents(
    rowid serial primary key,
    display_name varchar,
    unique(display_name)
);

create table clients(
    rowid serial primary key,
    parent int,
    display_name varchar,
    foreign key (parent) references parents(rowid),
    unique(display_name, parent)
);

create table datapoints(
    rowid serial primary key,
    client int,
    val float8,
    foreign key (client) references clients(rowid)
);

我正在获取包含 parent 名称、客户名称和一些值的数据。每次获取此数据时,我都想向数据点 table 添加行。我还想向客户端和 parents table 添加行,但前提是我收到的数据具有无法识别的名称。

例如,我可能会得到这个数据:

"parent1-client1-123.0"

我想要实现的是(在查询中)以这种方式处理此数据:

如果需要,在“parents”table 中插入一行。

如果需要,使用适当的 parent ID(在上一步中获得?)向“客户”table 插入一行。

使用适当的客户端 ID(在上一步中获得?)向“数据点”插入一行 table。

我如何通过查询来管理它?我的程序员想写:

但显然这不是 sql 的工作方式,对吧?如果我有 5 个或 10 个而不是这三个“嵌套”table 怎么办?(!)

请帮忙

Postgres 可以 return 插入时生成的键。不幸的是,当它遇到现有的唯一键和 on constraint 子句时,它不会 return 现有的键。 (一个猜测,但你可能已经发现了这一点。)然而,你的程序员离你不远了。您不是 检索并保存 id,而是直接通过 select 检索 检索并使用 。如果需要进行后续操作你只需'repeat'检索即可。因此,对于 3 级,您可以为第二级(客户端)和第三级(数据点)检索第一级值(父 rowid)。最好的(恕我直言)只是创建一个处理 3 个级别的过程。此外,在调用过程之前将输入分解为组件。结果过程变为:

create or replace procedure establisth_parent_client_datapoint(
                            parent_name_in  varchar
                          , client_name_in  varchar
                          , val_in          float8
                          ) 
  language sql 
as $$
    insert into parents (display_name)
         values (parent_name_in) 
         on conflict (display_name)
            do nothing;
                        
    insert into clients(display_name, parent) 
         select client_name_in 
              , p.rowid 
           from parents p 
          where p.display_name = parent_name_in 
        on conflict (display_name, parent)
           do nothing; 
          
    insert into datapoints(val, client) 
         select val_in, c.rowid 
           from parents p            
           join clients c 
             on ( c.parent = p.rowid) 
          where c.display_name = client_name_in
            and p.display_name = parent_name_in; 
$$; 

由于我不知道您的开发语言,我将在 Postgres DO block 中提供示例。参见 demo here
至于有 5-10 个嵌套表,您只需要为每个表重复基本过程。当然有 10 个嵌套表,我可能会质疑设计。