PSQL 查询根据条件将记录从一个 table 插入到另一个
PSQL query to insert the records from one table to another based on condition
我有 2 个具有以下结构的 Postgres table:
Table "public.tmp"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+---------
MY_SL | character varying(50) | | |
Release | character varying(50) | | |
HOST | character varying(50) | | not null |
UN NO. | character varying(50) | | |
STATUS | character varying(50) | | |
S_DATE | character varying(50) | | not null |
Table "public.mo"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+-----------------------------------------
id | integer | | not null | nextval('mbss_output_id_seq'::regclass)
HOST | character varying(50) | | not null |
UN NO. | character varying(50) | | |
STATUS | character varying(50) | | |
S_DATE | character varying(50) | | not null |
compliant_status | character varying(50) | | not null |
假设我在 tmp table 中有如下数据:
Table: tmp
MY_SL | Release | HOST | UN NO.| STATUS | S_DATE
------------+-------------+-----------+----------------------+------------------
2 | 1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26T15:16:48Z
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26T15:16:48Z
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26T15:16:48Z
4 | 1 | RhelTest | 7:2:10 | NC | 2020-08-26T15:16:48Z
11 | 2 | RhelTest | 7:2:11 | NC | 2020-08-26T15:16:48Z
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26T15:16:48Z
现在我想编写一个 psql INSERT INTO 查询,它将数据从 public.tmp 复制到 public.mo table 并执行以下条件
当主机在 STATUS 列中具有混合值时,例如,如果
主机:RhelTest
- 在 STATUS 列中有 2 个值作为 'COMPLIANT' 和 'NC' 那么列 compliant_status 应该有这样的行 'PARTIAL' 的值
- 或者如果只有一个值,如 'COMPLIANT',那么对于这样的行
,列 compliant_status 应该具有值 'COMPLIANT'
- 或者如果只有一个值,如 'NC',那么对于这样的行
,列 compliant_status 应该具有值 'NON_COMPLIANT'
public.mo table 中的最终预期输出:
Table: public.mo
id | HOST | UN NO.| STATUS | S_DATE | compliant_status
------------+-------------+-----------+----------------------+------------------
1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
2 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
3 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
4 | RhelTest | 7:2:10 | NC | 2020-08-26T15:16:48Z | PARTIAL
5 | RhelTest | 7:2:11 | NC | 2020-08-26T15:16:48Z | PARTIAL
6 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z | NON_COMPLIANT
7 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z | NON_COMPLIANT
8 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26T15:16:48Z | COMPLIANT
您可以使用 window 函数和 case
表达式。这是一种方法,假设 status
只有两个可能的值,如您的数据所示:
insert in mo (host, un_no, status, s_date, compliant_status)
select host, un_no, status, s_date,
case
when min_host_status <> max_host_status then 'PARTIAL'
when min_host_status = 'NC' then 'NON_COMPLIANT'
else min_host_status
end
from (
select t.*,
min(status) over(partition by host) min_host_status,
max(status) over(partition by host) max_host_status
from tmp t
) t
想法是比较每个 host
的 status
的最小值和最大值。如果有不同,则 compliant_status
是“PARTIAL”。否则,我们将“NC”变为“NON_COMPLIANT”,并保持另一个值(“COMPLIANT”)不变。
子查询在这里不是必须的,我们可以直接在外部查询中使用window函数;我使用它是因为它避免了一次又一次地重复相同的表达式。
我有 2 个具有以下结构的 Postgres table:
Table "public.tmp"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+---------
MY_SL | character varying(50) | | |
Release | character varying(50) | | |
HOST | character varying(50) | | not null |
UN NO. | character varying(50) | | |
STATUS | character varying(50) | | |
S_DATE | character varying(50) | | not null |
Table "public.mo"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+-----------------------------------------
id | integer | | not null | nextval('mbss_output_id_seq'::regclass)
HOST | character varying(50) | | not null |
UN NO. | character varying(50) | | |
STATUS | character varying(50) | | |
S_DATE | character varying(50) | | not null |
compliant_status | character varying(50) | | not null |
假设我在 tmp table 中有如下数据:
Table: tmp
MY_SL | Release | HOST | UN NO.| STATUS | S_DATE
------------+-------------+-----------+----------------------+------------------
2 | 1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26T15:16:48Z
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26T15:16:48Z
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26T15:16:48Z
4 | 1 | RhelTest | 7:2:10 | NC | 2020-08-26T15:16:48Z
11 | 2 | RhelTest | 7:2:11 | NC | 2020-08-26T15:16:48Z
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26T15:16:48Z
现在我想编写一个 psql INSERT INTO 查询,它将数据从 public.tmp 复制到 public.mo table 并执行以下条件
当主机在 STATUS 列中具有混合值时,例如,如果 主机:RhelTest
- 在 STATUS 列中有 2 个值作为 'COMPLIANT' 和 'NC' 那么列 compliant_status 应该有这样的行 'PARTIAL' 的值
- 或者如果只有一个值,如 'COMPLIANT',那么对于这样的行 ,列 compliant_status 应该具有值 'COMPLIANT'
- 或者如果只有一个值,如 'NC',那么对于这样的行 ,列 compliant_status 应该具有值 'NON_COMPLIANT'
public.mo table 中的最终预期输出:
Table: public.mo
id | HOST | UN NO.| STATUS | S_DATE | compliant_status
------------+-------------+-----------+----------------------+------------------
1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
2 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
3 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26T15:16:48Z | PARTIAL
4 | RhelTest | 7:2:10 | NC | 2020-08-26T15:16:48Z | PARTIAL
5 | RhelTest | 7:2:11 | NC | 2020-08-26T15:16:48Z | PARTIAL
6 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z | NON_COMPLIANT
7 | Demo1 | 7:2:11 | NC | 2020-08-26T15:16:48Z | NON_COMPLIANT
8 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26T15:16:48Z | COMPLIANT
您可以使用 window 函数和 case
表达式。这是一种方法,假设 status
只有两个可能的值,如您的数据所示:
insert in mo (host, un_no, status, s_date, compliant_status)
select host, un_no, status, s_date,
case
when min_host_status <> max_host_status then 'PARTIAL'
when min_host_status = 'NC' then 'NON_COMPLIANT'
else min_host_status
end
from (
select t.*,
min(status) over(partition by host) min_host_status,
max(status) over(partition by host) max_host_status
from tmp t
) t
想法是比较每个 host
的 status
的最小值和最大值。如果有不同,则 compliant_status
是“PARTIAL”。否则,我们将“NC”变为“NON_COMPLIANT”,并保持另一个值(“COMPLIANT”)不变。
子查询在这里不是必须的,我们可以直接在外部查询中使用window函数;我使用它是因为它避免了一次又一次地重复相同的表达式。