我在PL / SLQ功能中有以下情况。 根据现有的表字段值,我可能会运行不同的选择。 特别: 对于特定的BILL CODE(PINGPONG),我可以有多行,我只需要获取SYS_FIELD值。 根据以下条件,此字段只能获取一次: 如果字段prep_seq_num = 0且primary_ind = 0,则只需直接获取此行sys_field值,并且不处理其他可能的prep_seq_num和不同于0的primary_ind值。 如果该行不存在,则从prep_seq_num!= 0和primary_ind = 1中获取sys_field值。 对于这两种情况,只能有一个实例/行。 如果我有以下BILL表情况:
Tracking_ID BSCO_CODE_ID PREP_SEQ_NUM ITEM_CAT_CODE_ID PRIMARY_IND SYS_FIELD
1 PINGPONG 61 5 1 50
2 PINGPONG 0 1 0 100
然后我应该从sys_field中获取值100,其中prep_seq_num = 0
所以在第一种情况下我应该运行:
SELECT SYS_FIELD
INTO v_start_of_invoice
FROM BILL
WHERE TRACKING_ID = v_previous_trackingID
AND BSCO_CODE_ID = 'PINGPONG'
AND CHRG_ACCT_ID = v_ACCT_ID
AND PREP_SEQ_NUM = 0 -- maybe not needed here
AND ITEM_CAT_CODE_ID=1
AND PARTITION_KEY = v_prev_partition
AND SUBPARTITION_KEY = v_prev_subpartition
AND PRIMARY_IND=0;
在第二种情况下,如果我实际上只有以下内容(prep_seq_num = 0不存在)
Tracking_ID BSCO_CODE_ID PREP_SEQ_NUM ITEM_CAT_CODE_ID PRIMARY_IND SYS_FIELD
1 PINGPONG 61 5 1 50
我应该从sys_field获取值50,因此运行以下查询:
SELECT SYS_FIELD
INTO v_start_of_invoice
FROM BILL
WHERE TRACKING_ID = v_previous_trackingID
AND BILL_CODE_ID = 'PINGPONG'
AND ITEM_CAT_CODE_ID in ('5' , '-100')
AND PARTITION_KEY = v_prev_partition
AND SUBPARTITION_KEY = v_prev_subpartition
AND PRIMARY_IND=1;
我有很多想法,但没有一个真正有效我希望在一个查询中获得最有效/最快速度。 THKS
答案 0 :(得分:0)
您要寻找的是排名:您更喜欢prep_seq_num = 0 and primary_ind = 0
而不是prep_seq_num <> 0 and primary_ind = 1
。
执行此操作的典型方法是限制条款。这是标准SQL中的FETCH FIRST ROWS
,可从Oracle 12c开始提供。另一种选择是ROW_NUMBER
,它也是标准的SQL,自从我认为8i以来在Oracle中可用。
select sys_field
into v_start_of_invoice
from bill
where tracking_id = v_previous_trackingid
and bsco_code_id = 'PINGPONG'
and partition_key = v_prev_partition
and subpartition_key = v_prev_subpartition
and
(
(
prep_seq_num = 0 and
primary_ind = 0 and
item_cat_code_id = 1 and
chrg_acct_id = v_acct_id
)
or
(
prep_seq_num <> 0 and
primary_ind = 1 and
item_cat_code_id in (5, -100)
)
)
order by case when prep_seq_num = 0 then 1 else 2 end
fetch first 1 row only;
另一个选择是Oracle的KEEP FIRST
:
select max(sys_field) keep (dense_rank first
order by case when prep_seq_num = 0 then 1 else 2 end)
into v_start_of_invoice
...
<击> 撞击>
<击>order by case when prep_seq_num = 0 then 1 else 2 end
fetch first 1 row only;
击> <击> 撞击>
以下是ROW_NUMBER
的查询:
select sys_field
into v_start_of_invoice
from
(
select
sys_field,
row_number() over (order by case when prep_seq_num = 0 then 1 else 2 end) as rn
from bill
where tracking_id = v_previous_trackingid
and bsco_code_id = 'PINGPONG'
and partition_key = v_prev_partition
and subpartition_key = v_prev_subpartition
and
(
(
prep_seq_num = 0 and
primary_ind = 0 and
item_cat_code_id = 1 and
chrg_acct_id = v_acct_id
)
or
(
prep_seq_num <> 0 and
primary_ind = 1 and
item_cat_code_id in (5, -100)
)
)
)
where rn = 1;