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

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

想法是比较每个 hoststatus 的最小值和最大值。如果有不同,则 compliant_status 是“PARTIAL”。否则,我们将“NC”变为“NON_COMPLIANT”,并保持另一个值(“COMPLIANT”)不变。

子查询在这里不是必须的,我们可以直接在外部查询中使用window函数;我使用它是因为它避免了一次又一次地重复相同的表达式。