查询通过计算列上的百分比将记录插入另一个 table
query to insert records to another table by calculating the percentage on a column
我有 2 个具有以下结构的 Postgres table:
Table "public.tmp"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+---------
MY_SL | character varying(50) | | |
Release | character varying(50) | | |
HOSTNAME | 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('mo_id_seq'::regclass)
HOSTNAME | 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 |
C_PERCENT | character varying(50) | | not null |
假设我在 tmp table 中有如下数据:
Table: tmp
MY_SL | Release | HOSTNAME | UN NO.| STATUS | S_DATE
------------+-------------+-----------+----------------------+------------------
2 | 1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
4 | 1 | RhelTest | 7:2:10 | NC | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | NC | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
11 | 2 | RhelTest | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
432 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
111 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
321 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
564 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
958 | 3 | Demo3 | 7:2:11 | COMPLIANT | 2020-08-26
我在下面有一个脚本,它根据
的条件将数据从 public.tmp 插入到 public.mo table
- 如果列 STATUS 具有针对特定 HOSTNAME 的混合值(COMPLIANT 和 NC),则 compliant_status 是 PARTIAL 并且
- 如果特定主机名的所有值都符合,则 compliant_status 符合并且
- 如果特定主机名的所有值都是 NC,则 compliant_status 是 NON_COMPLIANT
insert into mo ("HOSTNAME","UN NO.","STATUS","S_DATE", compliant_status)
select "HOSTNAME","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 "HOSTNAME") min_host_status,
max("STATUS") over(partition by "HOSTNAME") max_host_status
from tmp_aix t
where "STATUS" != 'NOT_APPLICABLE'
) t;
现在我要根据以下条件显示compliant_status:
- 如果没有。特定 HOSTNAME 的 STATUS 列中的 COMPLIANT 值大于 80%,则 compliant_status 是 COMPLIANT。
- 如果没有。特定 HOSTNAME 的 STATUS 列中的 COMPLIANT 值小于 80%,则 compliant_status 为 NON_COMPLIANT。
根据以上数据,我期望最终输出如下:
主机名:RhelTest,
合规率:88.88%,
compliant_status:合规
主机名:Demo1,
符合 %: 0%,
compliant_status: NON_COMPLIANT
主机名:Demo2,
符合 %: 100%,
compliant_status:合规
主机名:Demo3,
合规率:16.67%,
compliant_status: NON_COMPLIANT
最终预期table:
Table: public.mo
HOSTNAME | UN NO. | STATUS | S_DATE | compliant_status | C_PERCENT
------------+-------------+-----------+----------------------+------------------
RhelTest | 7:1:8 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:10 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | NC | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo3 | 7:2:11 | COMPLIANT | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | COMPLIANT | 2020-08-26 | NON_COMPLIANT | 16.67
如果我没听错,你可以使用window功能:
select m.*,
100 * avg((compliant_status = 'COMPLIANT')::int) over(partition by hostname) c_percent
case when avg((compliant_status = 'COMPLIANT')::int) over(partition by hostname) >= 0.8
then 'COMPLIANT'
else 'NON_COMPLIANT'
end as final_compliant_status
from mo m
@GMB 感谢您的帮助。
以下查询帮助我满足了我的要求
insert into mo ("HOSTNAME","UN NO.","STATUS","S_DATE", compliant_status, c_percent)
select "HOSTNAME","UN NO.","STATUS","S_DATE",
case
when avg(("STATUS" = 'COMPLIANT')::int) over(partition by "HOSTNAME") >= 0.8
then 'COMPLIANT'
else 'NON_COMPLIANT'
end as compliant_status,
100 * avg(("STATUS" = 'COMPLIANT')::int) over(partition by "HOSTNAME") c_percent
from mo m
;
我有 2 个具有以下结构的 Postgres table:
Table "public.tmp"
Column | Type | Collation | Nullable | Default
-------------------+-------------------------+-----------+----------+---------
MY_SL | character varying(50) | | |
Release | character varying(50) | | |
HOSTNAME | 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('mo_id_seq'::regclass)
HOSTNAME | 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 |
C_PERCENT | character varying(50) | | not null |
假设我在 tmp table 中有如下数据:
Table: tmp
MY_SL | Release | HOSTNAME | UN NO.| STATUS | S_DATE
------------+-------------+-----------+----------------------+------------------
2 | 1 | RhelTest | 7:1:8 | COMPLIANT | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
4 | 1 | RhelTest | 7:2:10 | NC | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | COMPLIANT | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
12 | 1 | RhelTest | 7:1:9 | NC | 2020-08-26
22 | 2 | RhelTest | 7:2:1 | COMPLIANT | 2020-08-26
11 | 2 | RhelTest | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
1 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
23 | 3 | Demo1 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo2 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | COMPLIANT | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
432 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
111 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
333 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
321 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
564 | 3 | Demo3 | 7:2:11 | NC | 2020-08-26
958 | 3 | Demo3 | 7:2:11 | COMPLIANT | 2020-08-26
我在下面有一个脚本,它根据
的条件将数据从 public.tmp 插入到 public.mo table- 如果列 STATUS 具有针对特定 HOSTNAME 的混合值(COMPLIANT 和 NC),则 compliant_status 是 PARTIAL 并且
- 如果特定主机名的所有值都符合,则 compliant_status 符合并且
- 如果特定主机名的所有值都是 NC,则 compliant_status 是 NON_COMPLIANT
insert into mo ("HOSTNAME","UN NO.","STATUS","S_DATE", compliant_status)
select "HOSTNAME","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 "HOSTNAME") min_host_status,
max("STATUS") over(partition by "HOSTNAME") max_host_status
from tmp_aix t
where "STATUS" != 'NOT_APPLICABLE'
) t;
现在我要根据以下条件显示compliant_status:
- 如果没有。特定 HOSTNAME 的 STATUS 列中的 COMPLIANT 值大于 80%,则 compliant_status 是 COMPLIANT。
- 如果没有。特定 HOSTNAME 的 STATUS 列中的 COMPLIANT 值小于 80%,则 compliant_status 为 NON_COMPLIANT。
根据以上数据,我期望最终输出如下:
主机名:RhelTest, 合规率:88.88%, compliant_status:合规
主机名:Demo1, 符合 %: 0%, compliant_status: NON_COMPLIANT
主机名:Demo2, 符合 %: 100%, compliant_status:合规
主机名:Demo3, 合规率:16.67%, compliant_status: NON_COMPLIANT
最终预期table:
Table: public.mo
HOSTNAME | UN NO. | STATUS | S_DATE | compliant_status | C_PERCENT
------------+-------------+-----------+----------------------+------------------
RhelTest | 7:1:8 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:10 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:1:9 | NC | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:1 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
RhelTest | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 88.88
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo1 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 0
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo2 | 7:2:11 | COMPLIANT | 2020-08-26 | COMPLIANT | 100
Demo3 | 7:2:11 | COMPLIANT | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | NC | 2020-08-26 | NON_COMPLIANT | 16.67
Demo3 | 7:2:11 | COMPLIANT | 2020-08-26 | NON_COMPLIANT | 16.67
如果我没听错,你可以使用window功能:
select m.*,
100 * avg((compliant_status = 'COMPLIANT')::int) over(partition by hostname) c_percent
case when avg((compliant_status = 'COMPLIANT')::int) over(partition by hostname) >= 0.8
then 'COMPLIANT'
else 'NON_COMPLIANT'
end as final_compliant_status
from mo m
@GMB 感谢您的帮助。 以下查询帮助我满足了我的要求
insert into mo ("HOSTNAME","UN NO.","STATUS","S_DATE", compliant_status, c_percent)
select "HOSTNAME","UN NO.","STATUS","S_DATE",
case
when avg(("STATUS" = 'COMPLIANT')::int) over(partition by "HOSTNAME") >= 0.8
then 'COMPLIANT'
else 'NON_COMPLIANT'
end as compliant_status,
100 * avg(("STATUS" = 'COMPLIANT')::int) over(partition by "HOSTNAME") c_percent
from mo m
;