简体   繁体   English

从oracle表中删除特定行

[英]Deleting specific rows from oracle table

I have to delete the specific rows from oracle table.我必须从 oracle 表中删除特定的行。 Below is the table structure.下面是表结构。

  1. For Item Id 1234 where more than 1 row with Cancel state exists it should delete last 2 rows of Cancel State such that only two records remains in table with 02/Apr/2021 to 04/June/2021 and 05/June/2021 to 06/June/2021(also 06/June/2021 gets updated to 31/Dec/3033).对于存在超过 1 行具有取消状态的Item Id 1234,它应该删除取消状态的最后 2 行,以便在 02/Apr/2021 至 04/June/2021 和 05/June/2021 至 06 的表中仅保留两条记录/June/2021(也将 06/June/2021 更新为 31/Dec/3033)。 I have to identify all the rows where more than 1 Cancel State along with one Active state exists and then have to delete all the cancel rows except 1 cancel row and then have to update item end date to max date for that row.我必须确定存在 1 个以上取消状态和一个活动状态的所有行,然后必须删除除 1 个取消行之外的所有取消行,然后必须将项目结束日期更新为该行的最大日期。

  2. For Item Id 1235, since only one row exits of Cancel state it should gets deleted from the table.对于Item Id 1235,由于只有一行退出 Cancel 状态,因此应该从表中删除它。 I have to identify all such rows where state is only Cancel and no Active state row exists for that Item Id and then delete them.我必须识别所有此类行,其中状态仅为取消且该项目 ID 不存在活动状态行,然后将其删除。

  3. For Item Id 1236, its a perfect state therefore nothing should happenes to such rows.对于Item Id 1236,它是一个完美的状态,因此这些行不会发生任何事情。

Item Id商品编号 Item State物品状态 Item Start Date项目开始日期 Item End Date项目结束日期
1234 1234 Active积极的 02/Apr/2021 2021/4/02 04/June/2021 04/六月/2021
1234 1234 Cancel取消 05/June/2021 05/六月/2021 06/June/2021 06/六月/2021
1234 1234 Cancel取消 07/June/2021 07/六月/2021 30/June/2021 2021 年 6 月 30 日
1234 1234 Cancel取消 01/July/2021 01/七月/2021 31/Dec/3033 31/Dec/3033
1235 1235 Cancel取消 03/Apr/2021 03/Apr/2021 03/Apr/2021 03/Apr/2021
1236 1236 Active积极的 04/Apr/2021 04/Apr/2021 05/May/2021 2021 年 5 月 5 日
1236 1236 Cancel取消 06/May/2021 2021 年 5 月 6 日 31/Dec/3033 31/Dec/3033

After deleting specific rows table would change to something like below删除特定行表后将更改为如下所示

Item Id商品编号 Item State物品状态 Item Start Date项目开始日期 Item End Date项目结束日期
1234 1234 Active积极的 02/Apr/2021 2021/4/02 04/June/2021 04/六月/2021
1234 1234 Cancel取消 05/June/2021 05/六月/2021 31/Dec/3033 31/Dec/3033
1236 1236 Active积极的 04/Apr/2021 04/Apr/2021 05/May/2021 2021 年 5 月 5 日
1236 1236 Cancel取消 06/May/2021 2021 年 5 月 6 日 31/Dec/3033 31/Dec/3033

Please suggest pointers to get this done.请提出建议以完成这项工作。 Can this be done using sql alone ?I have not done coding in PL/SQL before.这可以单独使用 sql 来完成吗?我以前没有在 PL/SQL 中做过编码。

Many many thanks in advance.非常感谢提前。

Indeed it is possible in SQL.事实上,它在 SQL 中是可能的。 Here is what worked for me.这对我有用。 The below snippet will hold details for Item IDs in active state:以下代码段将包含处于active状态的项目 ID 的详细信息:

create table active as 
select * 
from
(select id, state, count(*) as flg from itm group by id, state)
where state='Active';

Similarly, in the below snippet, creating a table for Item IDs in Cancel state:同样,在下面的代码段中,为处于Cancel状态的项目 ID 创建一个表:

create table cancel as 
select * 
from
(select id, state, count(*) as flg from itm group by id, state)
where state='Cancel';

Note that I've created flg variable which holds number of records with active and cancel respectively.请注意,我创建了 flg 变量,该变量分别保存了activecancel的记录数。

The below code snippet will ignore perfect Item IDs (ie, 1236) for now.下面的代码片段暂时将忽略完美的Item IDs (即 1236)。

create table target as
select a.id as a_id, a.state as a_state, a.flg as a_flg, c.* 
from active as a 
full join cancel as c 
    on a.id=c.id
where a.flg <> c.flg;

Below code will help us to get Item IDs that needs to be analysed.下面的代码将帮助我们获取需要分析的Item IDs

create table ads as select *, count(*) as cnt 
from itm
where 
 id IN (select distinct a_id from target where a_id IS NOT NULL)
 or 
 id IN (select distinct id from target where id IS NOT NULL)
group by id 
order by id, state, start_date, end_date;

/* The below snippet is to delete any record with only cancel */ /* 下面的片段是删除任何记录,只取消 */

create table fin_ads as 
select * from ads
where cnt <> 1;

Below snippet will give us the final results下面的代码片段将为我们提供最终结果

    /* The below snippet is to stitch records with multiple cancel */
    select id, state, min(start_date) as start format=date9., max(end_date) as end format=date9. 
from fin_ads
    group by id, state
    UNION
    /* UNION is used to combine the perfect Item IDs back to the result */
    select id, state, start_date as start, end_date as end from itm 
    where id IN
    (
    select distinct a.id
    from active as a 
    inner join cancel as c 
    on a.id=c.id
    where a.flg =c.flg)

I know this is not an optimized query and is long.我知道这不是优化的查询并且很长。 Yet this gives the result as expected.然而,这给出了预期的结果。 Note: Use sub-queries to reduce number of intermediate tables getting created.注意:使用子查询来减少创建的中间表的数量。 Hope this helps!希望这可以帮助! Do let me know if this works/ facing any issues.请让我知道这是否有效/面临任何问题。

Do you want to delete and update rows in your table or merely select the described result from your table?您是要删除和更新表中的行还是仅从表中选择描述的结果?

Then it looks like there is always at most one active row per item in the table.然后看起来表格中的每个项目总是最多有一个活动行。 Your result hence shows the items with one row per status and their minimum start date and maximum end date.因此,您的结果显示每个状态一行的项目及其最短开始日期和最长结束日期。

The following simple query may hence already do what you want to do:因此,以下简单查询可能已经完成了您想做的事情:

select
  item_id,
  item_state,
  min(item_start_date) as item_state_start_date,
  max(item_end_date) as item_state_end_date
from mytable
group by item_id, item_state
order by item_id, item_state;

This selects rows.这将选择行。 If you want to delete and update rows instead, you can simpy create a table from the above result, delete rows in your original table and fill the table from the newly created one.如果你想删除和更新行,你可以简单地从上面的结果创建一个表,删除原始表中的行并从新创建的表中填充该表。 (Or create the new table, drop the old one, rename the new one.) (或创建新表,删除旧表,重命名新表。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM