我必須從 oracle 表中洗掉特定的行。下面是表結構。
對于
Item Id存在超過 1 行具有取消狀態的 1234,它應該洗掉取消狀態的最后 2 行,以便在 02/Apr/2021 至 04/June/2021 和 05/June/2021 至 06/June 的表中僅保留兩條記錄/2021(也是 06/June/2021 更新為 31/Dec/3033)。我必須確定存在 1 個以上取消狀態和一個活動狀態的所有行,然后必須洗掉除 1 個取消行之外的所有取消行,然后必須將專案結束日期更新為該行的最大日期。對于
Item Id1235,由于只有一行退出取消狀態,它應該從表中洗掉。我必須識別所有此類行,其中狀態僅為取消且該專案 ID 不存在活動狀態行,然后將其洗掉。對于
Item Id1236,它是一個完美的狀態,因此這些行不應該發生任何事情。
| 商品編號 | 物品狀態 | 專案開始日期 | 專案結束日期 |
|---|---|---|---|
| 1234 | 積極的 | 2021/4/02 | 04/六月/2021 |
| 1234 | 取消 | 05/六月/2021 | 06/六月/2021 |
| 1234 | 取消 | 07/六月/2021 | 2021 年 6 月 30 日 |
| 1234 | 取消 | 01/七月/2021 | 31/Dec/3033 |
| 1235 | 取消 | 03/Apr/2021 | 03/Apr/2021 |
| 1236 | 積極的 | 04/Apr/2021 | 2021 年 5 月 5 日 |
| 1236 | 取消 | 2021 年 5 月 6 日 | 31/Dec/3033 |
洗掉特定行表后將更改為如下所示
| 商品編號 | 物品狀態 | 專案開始日期 | 專案結束日期 |
|---|---|---|---|
| 1234 | 積極的 | 2021/4/02 | 04/六月/2021 |
| 1234 | 取消 | 05/六月/2021 | 31/Dec/3033 |
| 1236 | 積極的 | 04/Apr/2021 | 2021 年 5 月 5 日 |
| 1236 | 取消 | 2021 年 5 月 6 日 | 31/Dec/3033 |
請提出建議以完成這項作業。這可以單獨使用 sql 來完成嗎?我以前沒有在 PL/SQL 中做過編碼。
非常感謝提前。
uj5u.com熱心網友回復:
事實上,它在 SQL 中是可能的。這對我有用。下面的代碼段將保存active狀態中專案 ID 的詳細資訊:
create table active as
select *
from
(select id, state, count(*) as flg from itm group by id, state)
where state='Active';
類似地,在下面的代碼段中,為處于Cancel狀態的專案 ID 創建一個表:
create table cancel as
select *
from
(select id, state, count(*) as flg from itm group by id, state)
where state='Cancel';
請注意,我已經創建了 flg 變數,它分別保存了active和的記錄數cancel。
下面的代碼片段暫時將忽略完美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;
下面的代碼將幫助我們獲得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;
/* 下面的片段是洗掉任何記錄,只取消 */
create table fin_ads as
select * from ads
where cnt <> 1;
下面的代碼片段將為我們提供最終結果
/* 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)
我知道這不是優化的查詢并且很長。然而,這給出了預期的結果。注意:使用子查詢來減少創建的中間表的數量。希望這可以幫助!請讓我知道這是否有效/面臨任何問題。
uj5u.com熱心網友回復:
您是要洗掉和更新表中的行還是僅從表中選擇描述的結果?
然后看起來表格中的每個專案總是最多有一個活動行。因此,您的結果顯示每個狀態一行的專案及其最短開始日期和最長結束日期。
因此,以下簡單查詢可能已經完成了您想做的事情:
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;
這將選擇行。如果你想洗掉和更新行,你可以簡單地從上面的結果創建一個表,洗掉原始表中的行并從新創建的表中填充該表。(或創建新表,洗掉舊表,重命名新表。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/336357.html
上一篇:如何在Oracle中將`(Ab56.12345)some_string`的一列字串拆分為兩列`Ab.12345`、`some_string`
下一篇:工資低于部門平均水平的員工
