如何在同一个表中选择同一个表2不同的条件(Oracle存储过程)

时间:2017-06-17 16:25:47

标签: sql oracle stored-procedures

我有一个包含4个库仑的表和一个从该表中选择的存储过程。 DOC_ID; CUSTOMER_TYPE_ID; CATEGORY_ID; REQUIERD_STATUS; 到目前为止,select通过传递customerId的params和categoryCode,我们得到了docId和requierdStatus

现在我想添加另一列" Activity_ID"(可空)设置活动代码,以便我们更具体。 例如:到现在为止 custTypeId = 1,CategoryCode = 2 给了我2行 custTypeId = 1,DocId = 1,requierdStatus = 3,CategoryCode = 2 custTypeId = 1,DocId = 2,requierdStatus = 3,CategoryCode = 2

通过添加activityCode coulmn,我们想要像这样控制所需的状态 DocId = 1,requierdStatus = 3,CategoryCode = 2,ActivityId = null DocId = 1,requierdStatus = 4,CategoryCode = 2,ActivityId = 10

基本上,如果文档没有特定的activityCode,那么它应该由类别选择。

在我的选择中,我需要能够通过ActivityId选择,但如果没有回答该条件的行,那么我想按类别获取行。 不可能发生的是,我将获得两行,一行按活动,另一行按类别。

我应该只获得一行或零。

我该怎么做?

感谢。

2 个答案:

答案 0 :(得分:0)

在了解了您的问题后,解决方案可能会对您有所帮助。

CREATE PROCEDURE proc_Search 
   @Activity_Id INT NULL,
   @CustTypeID INT ,
   @CategoryCode INT
AS 
BEGIN
 SELECT DOC_ID, CUSTOMER_TYPE_ID,CATEGORY_ID, REQUIERD_STATUS
 FROM myTable
 WHERE @Activity_ID IS NULL OR (Activity_ID = @Activity_ID)
 AND CATEGORY_ID = @CategoryCode

END 

答案 1 :(得分:0)

如果我理解你在做什么,你似乎想要:

select min(t.doc_id) keep (dense_rank first order by t.activity_id),
  min(t.required_status) keep (dense_rank first order by t.activity_id)
into ... -- unless opening a ref cursor
from your_table t
where t.customer_type_id = p_customer_type_id
and (t.activity_id = p_activity_id
 or (t.activity_id is null and t.category_id = p_category_id))
group by t.customer_type_id, t.category_id;

其中p_customer_type_idp_category_idp_activity_id是您的过程的参数。假设你只想回到按类别搜索,表活动ID是null,我认为这就是你所描述的。并且传递给过程的值也不会为null;如果它可以那么只是让它复杂一点。

Read more about the keep dense_rank first construct.基本上它决定了分组数据中的哪一行保存在结果集中。

使用您的样本数据进行快速演示(如果我的解释正确......):

create table your_table (doc_id number, customer_type_id number,
  category_id number, required_status number, activity_id number);

insert into your_table (doc_id, customer_type_id,
  category_id, required_status, activity_id)
values (1, 1, 2, 3, null);

insert into your_table (doc_id, customer_type_id,
  category_id, required_status, activity_id)
values (1, 1, 2, 4, 10);

作为具有OUT引用游标参数的过程:

create or replace procedure your_proc (p_customer_type_id number,
  p_category_id number, p_activity_id number, p_cursor out sys_refcursor) as
begin
  open p_cursor for
    select min(t.doc_id) keep (dense_rank first order by t.activity_id) as doc_id,
      min(t.required_status) keep (dense_rank first order by t.activity_id) as required_status
    from your_table t
    where t.customer_type_id = p_customer_type_id
    and (t.activity_id = p_activity_id
     or (t.activity_id is null and t.category_id = p_category_id))
    group by t.customer_type_id, t.category_id;
end your_proc;
/

然后测试它:

var rc refcursor;

begin
  your_proc (p_customer_type_id => 1, p_category_id => 2,
    p_activity_id => 10, p_cursor => :rc);
end;
/

PL/SQL procedure successfully completed.

print rc

    DOC_ID REQUIRED_STATUS
---------- ---------------
         1               4

begin
  your_proc (p_customer_type_id => 1, p_category_id => 2,
    p_activity_id => 42, p_cursor => :rc);
end;
/

PL/SQL procedure successfully completed.

print rc

    DOC_ID REQUIRED_STATUS
---------- ---------------
         1               3