PG数据库--表继承

一、表继承

  1. 父表与子表的关系,表访问权限并不会自动继承。
  2. 当在父表上查询数据的时候,想要知道那些出自于主表,哪些出自于继承表。可以利用tableoid,来标识数据来自于那一个表,然后再通过tableoid在pg_class表中找到对用的表 。
  3. postgresql里,一个表可以从零个或者多个其它表中继承属性,而且一个查询既可以引用一个表中的所有行,也可以引用一个表及其所有后代表的行。
  4. 子表会继承父表的所有属性
  5. 当我们向子表中插入数据的时候,父表中也会增加一条数据。
  6. 所有父表的检查约束和非空约束都会自动被子表继承。不过其他类型的约束(唯一,主键,外键约束)不会被继承。继承的一个严重局限性是索引(包括唯一约束)和外键约束只能用于单个表,而不能包括他们的子表。
  7. 如果需要继承主键和约束条件,索引等,则需要在创建的时候加上Including all 
  8. create table md_table_01(like md_table including all) inherits (md_table);
  9. 表继承通常使用 inherits 子句的 create table语句定义。
  10. 一个继承链可以使用带 no inherit 的 alter table 命令从子表上删除。
  11. alter table md_table_01 no inherit md_table;
  12. 任何存在子表的父表都不能被删除,子表中任何从父表继承的字段或约束也不能被删除或修改。
  13. 删除一个表以及其所有后代,最简单的方式是使用cascade选项删除父表。
 drop table md_table cascade;

二、ddl

        1、继承案例

父表:
CREATE TABLE
    ods_v2_yy_01_z82remrsd2
    (
        id CHARACTER VARYING(32) NOT NULL,
        mm_id CHARACTER VARYING(32) NOT NULL,
        md_name CHARACTER VARYING(64) NOT NULL,
        alias_md_name CHARACTER VARYING(128) NOT NULL,
        dw_md_name CHARACTER VARYING(63) NOT NULL,
        md_type CHARACTER VARYING(32) NOT NULL,
        md_attr CHARACTER VARYING(32),
        CONSTRAINT pk_v2_yy_01_z82rgvsefn PRIMARY KEY (id)
    );

子表:
create table ods_v2_yy_01_z82remrsd2_2021(like ods_v2_yy_01_z82remrsd2) inherits(ods_v2_yy_01_z82remrsd2);
create table ods_v2_yy_01_z82remrsd2_2022(like ods_v2_yy_01_z82remrsd2) inherits(ods_v2_yy_01_z82remrsd2);
create table ods_v2_yy_01_z82remrsd2_2023(like ods_v2_yy_01_z82remrsd2) inherits(ods_v2_yy_01_z82remrsd2);

        2.只查询父表的数据,表名前面加only

select * from ods_v2_yy_01_z82remrsd2 where id>10

        3. 查询全部,可以在表名加上*,也可以不加,不过写在表后面 写 乘号可以用于强调搜索额外的表。

select name,altitude from ods_v2_yy_01_z82remrsd2* where id>500;

### 使用 PostgreSQL 查询结果自动生成 `INSERT INTO` 语句 为了实现从一个查询数据并将其插入另一个的功能,可以通过构建 SQL 字符串来完成这一操作。具体方法涉及组合 `SELECT` 和字符串拼接功能。 对于动态生成 `INSERT INTO` 语句的任务,可以采用以下方式: #### 方法一:直接使用 `INSERT INTO...SELECT` 最简单的方法是直接利用 `INSERT INTO target_table SELECT * FROM source_table WHERE condition;` 的形式[^1]。这种方式不需要显式地构造完整的 `VALUES` 列,而是让 PostgreSQL 自动处理源中的每一行,并相应地插入目标中。 ```sql -- 假设source_table是要从中读取数据的原始格, -- 而target_table是我们希望写入的新格。 INSERT INTO target_table (col1, col2, ...) SELECT col1, col2, ... FROM source_table; ``` 这种方法适用于两结构相同的情况;如果列名不同,则需指定对应关系。 #### 方法二:通过 PL/pgSQL 构建动态 SQL 插入语句 当需要更灵活控制时,比如只复制部分符合条件的数据或调整字段顺序/名称映射,可借助存储过程或者匿名代码块(do命令),编写一段PL/pgSQL脚本来执行此任务[^2]。 下面是一个简单的例子展示如何创建这样的函数: ```plpgsql DO $$ DECLARE rec RECORD; BEGIN FOR rec IN EXECUTE format('SELECT id,name,address FROM %I', 'oldtable') LOOP EXECUTE format( 'INSERT INTO newtable(id,name,addr) VALUES (%L,%L,%L)', rec.id, rec.name, CASE WHEN rec.address IS NULL THEN '无地址' ELSE rec.address END); END LOOP; END $$ LANGUAGE plpgsql; ``` 这段代码遍历旧(`oldtable`)里的每一条记录,并逐条插入到新(`newtable`)里,在这个过程中还可以对某些特定情况进行特殊处理,例如这里假设address为空则替换为默认值"无地址"。 #### 方法三:基于元数据自动构建批量插入语句 另一种高级做法是从系统目录获取有关的信息,从而自动化整个流程。这通常涉及到访问pg_class、information_schema.columns等视图以获得关于及其属性的知识[^3]。 以下是简化版的例子说明如何做到这一点: ```sql WITH cols AS ( SELECT string_agg(column_name::text,', ') as columns, string_agg(format('%I = EXCLUDED.%I', column_name, column_name), ', ') OVER () as update_cols FROM information_schema.columns WHERE table_name='your_source_table' AND ordinal_position<=5 -- 只考虑前五列作为示范目的 ) SELECT concat_ws(E'\n', 'INSERT INTO your_target_table(',cols.columns,') ', 'SELECT ',cols.columns,' FROM your_source_table;', 'ON CONFLICT DO NOTHING;' ) FROM cols; ``` 上述查询会返回一个准备好的 `INSERT INTO ... ON CONFLICT DO NOTHING` 形式的SQL语句,它可以从给定的源选取所需列并将它们插入到目标中,同时避免重复键冲突引发错误[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值