处理重复配置
Handle Duplicate Configurations
我有一个 table 记录如下
No. Parameter STATUS
1 STO INACTIVE
2 STO ACTIVE
3 BOS ACTIVE
4 KYC INACTIVE
5 KYC INACTIVE
6 ACC ACTIVE
7 ACC ACTIVE
现在我感兴趣的结果如下:
No. Parameter STATUS
2 STO ACTIVE
3 BOS ACTIVE
4 KYC INACTIVE
6 ACC ACTIVE
也就是说,我想在 STATUS 的基础上 select 数据。
条件——如果 STATUS 是 ACTIVE 对于相同参数的两种情况 - select 先到 ACTIVE
条件——如果 STATUS 是 INACTIVE 对于相同参数的两种情况 - select 先到 INACTIVE
条件 -- 如果状态为 ACTIVE & INACTIVE 对于同一参数 - select 活跃
请帮助我在我的程序中编写相同的查询。
一种方法是 UNION ALL 解决方案,第一部分选择 ACTIVE 行,第二部分仅当不存在活动时才选择 INACTIVE 位:
select No, Parameter, STATUS from table
where status = 'ACTIVE'
UNION ALL
select No, Parameter, STATUS from table t
where status = 'INACTIVE' and not exists (select * from table
where parameter = t.parameter
and status = 'ACTIVE')
order by no, parameter
或者,也许更好 - 现已改进
select MIN(No) as No, Parameter, STATUS
from table t
where status = 'ACTIVE' or not exists (select * from table
where parameter = t.parameter
and status = 'ACTIVE')
group by Parameter, STATUS
order by no, parameter
我认为你可以用条件聚合做你想做的事:
select parameter,
max(case when min(status) = max(status) then max(status) else 'ACTIVE' end) as status,
coalesce(min(case when status = 'ACTIVE' then id end), min(id)) as id
from table t
group by parameter;
这种优先级排序的另一种方法是使用 row_number()
:
select parameter, status, id
from (select t.*,
row_number() over (partition by parameter
order by status asc, id
) as seqnum
from table t
) t
where seqnum = 1;
注意:order by status asc
使用 ACTIVE
按字母顺序排在 INACTIVE
之前的事实。这只是合并该逻辑的最简单方法。
编辑(来自 Silvain):
SQL Fiddle 是 here.
我在 CURSOR 中使用了以下查询
CURSOR cCnfgTypData IS
select distinct name, description, STATUS
from stg_xml_cpdb_configuration
WHERE process_exec_num = 1
AND STATUS = 'ACTIVE'
UNION ALL
select name, description, STATUS
from stg_xml_cpdb_configuration t
where process_exec_num = 1
and STATUS = 'INACTIVE'
and not exists (select * from stg_xml_cpdb_configuration
where name = t.name
and STATUS = 'ACTIVE') order by name, description;
我可以检索数据,但我还想要另外两个列数据(一个是唯一约束)。
我使用了下面的代码 -
CURSOR cCnfgTypData IS
select distinct name, description, STATUS, xml_configparamdb_id, xml_configuration_id
from stg_xml_cpdb_configuration
WHERE process_exec_num = 1
AND STATUS = 'ACTIVE'
UNION ALL
select name, description, STATUS, xml_configparamdb_id, xml_configuration_id
from stg_xml_cpdb_configuration t
where process_exec_num = 1
and STATUS = 'INACTIVE'
and not exists (select * from stg_xml_cpdb_configuration
where name = t.name
and STATUS = 'ACTIVE') order by name, description;
但是现在我得到了所有不满足条件的记录
1.Condition -- 如果对于相同参数的两种情况,STATUS 都是 ACTIVE - select 首先是 ACTIVE
2.Condition -- 如果对于相同参数的两种情况,STATUS 都为 INACTIVE - select 首先出现 INACTIVE
3.Condition -- 如果同一参数的状态为活动和非活动 - select 活动
注意 - 这里,xml_configuration_id 包含唯一数据
我有一个 table 记录如下
No. Parameter STATUS
1 STO INACTIVE
2 STO ACTIVE
3 BOS ACTIVE
4 KYC INACTIVE
5 KYC INACTIVE
6 ACC ACTIVE
7 ACC ACTIVE
现在我感兴趣的结果如下:
No. Parameter STATUS
2 STO ACTIVE
3 BOS ACTIVE
4 KYC INACTIVE
6 ACC ACTIVE
也就是说,我想在 STATUS 的基础上 select 数据。
条件——如果 STATUS 是 ACTIVE 对于相同参数的两种情况 - select 先到 ACTIVE
条件——如果 STATUS 是 INACTIVE 对于相同参数的两种情况 - select 先到 INACTIVE
条件 -- 如果状态为 ACTIVE & INACTIVE 对于同一参数 - select 活跃
请帮助我在我的程序中编写相同的查询。
一种方法是 UNION ALL 解决方案,第一部分选择 ACTIVE 行,第二部分仅当不存在活动时才选择 INACTIVE 位:
select No, Parameter, STATUS from table
where status = 'ACTIVE'
UNION ALL
select No, Parameter, STATUS from table t
where status = 'INACTIVE' and not exists (select * from table
where parameter = t.parameter
and status = 'ACTIVE')
order by no, parameter
或者,也许更好 - 现已改进
select MIN(No) as No, Parameter, STATUS
from table t
where status = 'ACTIVE' or not exists (select * from table
where parameter = t.parameter
and status = 'ACTIVE')
group by Parameter, STATUS
order by no, parameter
我认为你可以用条件聚合做你想做的事:
select parameter,
max(case when min(status) = max(status) then max(status) else 'ACTIVE' end) as status,
coalesce(min(case when status = 'ACTIVE' then id end), min(id)) as id
from table t
group by parameter;
这种优先级排序的另一种方法是使用 row_number()
:
select parameter, status, id
from (select t.*,
row_number() over (partition by parameter
order by status asc, id
) as seqnum
from table t
) t
where seqnum = 1;
注意:order by status asc
使用 ACTIVE
按字母顺序排在 INACTIVE
之前的事实。这只是合并该逻辑的最简单方法。
编辑(来自 Silvain):
SQL Fiddle 是 here.
我在 CURSOR 中使用了以下查询
CURSOR cCnfgTypData IS
select distinct name, description, STATUS
from stg_xml_cpdb_configuration
WHERE process_exec_num = 1
AND STATUS = 'ACTIVE'
UNION ALL
select name, description, STATUS
from stg_xml_cpdb_configuration t
where process_exec_num = 1
and STATUS = 'INACTIVE'
and not exists (select * from stg_xml_cpdb_configuration
where name = t.name
and STATUS = 'ACTIVE') order by name, description;
我可以检索数据,但我还想要另外两个列数据(一个是唯一约束)。 我使用了下面的代码 -
CURSOR cCnfgTypData IS
select distinct name, description, STATUS, xml_configparamdb_id, xml_configuration_id
from stg_xml_cpdb_configuration
WHERE process_exec_num = 1
AND STATUS = 'ACTIVE'
UNION ALL
select name, description, STATUS, xml_configparamdb_id, xml_configuration_id
from stg_xml_cpdb_configuration t
where process_exec_num = 1
and STATUS = 'INACTIVE'
and not exists (select * from stg_xml_cpdb_configuration
where name = t.name
and STATUS = 'ACTIVE') order by name, description;
但是现在我得到了所有不满足条件的记录
1.Condition -- 如果对于相同参数的两种情况,STATUS 都是 ACTIVE - select 首先是 ACTIVE
2.Condition -- 如果对于相同参数的两种情况,STATUS 都为 INACTIVE - select 首先出现 INACTIVE
3.Condition -- 如果同一参数的状态为活动和非活动 - select 活动
注意 - 这里,xml_configuration_id 包含唯一数据