光标与where条件

时间:2016-12-15 10:18:57

标签: database oracle loops cursor

我有一个光标,其中包含按姓氏分组的所有人的账单。现在,我想动态检查哪个姓氏有针对它的未付帐单。例如。有亚当斯和佩里家族等等。光标具有族的所有成员的值,其中一列是族名。现在我检查了未付金额,我发现他们是亚当斯家族中的一个。现在,我希望我的光标显示adams家族的所有成员,这样我就可以将账单分发给家庭的其他成员。

CURSOR individual_cur is
select name,family_name, bill from table1;

CURSOR family_cur is
    select family_name from table1;

    for temp in family_cur loop
    select sum(bill) into extra_bill where family_name is temp.family_name;

    if extra_bill <>0 then

    -- Now here I want 
    for temp1 in individual_cur loop *where family_name is temp.family_name*

    -- How to do this.
    end loop;

2 个答案:

答案 0 :(得分:1)

这是一个例子

declare
   -- add family name as parameter
   -- and use in where clause
   cursor individual_cur(p_family_name table1.family_name%type) is
      select name
            ,family_name
            ,bill
        from table1
       where family_name = p_family_name;

   --group by family 
   -- and filter on sum(bill)<>0
   cursor family_cur is
      select family_name
        from table1
       group by family_name
       having sum(bill)<>0;
begin

   for temp in family_cur
   loop
        -- select individuals from this family
         for temp1 in individual_cur(temp.family_name)
         loop

           -- do something
        end loop;
   end loop;
end;

或仅在一个查询中

 select name
       ,family_name
       ,bill
   from table1
  where family_name in (select family_name
                        from table1
                        group by family_name
                        having sum(bill)<>0)

答案 1 :(得分:0)

我认为你要做的是平均所有家庭成员的账单?如果是这样,那么这可以在一个查询中完成:

WITH table1 AS (SELECT 'bob' NAME, 'jones' family_name, 0 bill FROM dual UNION ALL
                SELECT 'jane', 'jones', 100 bill FROM dual UNION ALL
                SELECT 'fred', 'jones', 50 bill FROM dual UNION ALL
                SELECT 'bill', 'smith', 0 bill FROM dual UNION ALL
                SELECT 'brenda', 'smith', 60 bill FROM dual UNION ALL
                SELECT 'jill', 'smith', 0 bill FROM dual UNION ALL
                SELECT 'bob', 'ingles', 0 bill FROM dual UNION ALL
                SELECT 'carol', 'ingles', 0 bill FROM dual UNION ALL
                SELECT 'rob', 'carolgees', 200 bill FROM dual)
-- end of mimicking your table1 with sample data in it - you wouldn't need this
-- see the SQL below
SELECT NAME,
       family_name,
       bill,
       AVG(bill) OVER (PARTITION BY family_name) split_bill
FROM   table1;

NAME   FAMILY_NAME       BILL SPLIT_BILL
------ ----------- ---------- ----------
rob    carolgees          200        200
carol  ingles               0          0
bob    ingles               0          0
fred   jones               50         50
bob    jones                0         50
jane   jones              100         50
jill   smith                0         20
bill   smith                0         20
brenda smith               60         20

这使用AVG()分析函数在家庭中的所有成员之间拆分帐单,而不压缩像AVG()聚合函数那样的行。

如果您需要更新table1以反映共享账单,则可以将上述查询插入MERGE语句,如:

merge into table1 tgt
  using (select name,
                family_name,
                bill,
                avg(bill) over (partition by family_name) split_bill
         from   table1) src
    on (tgt.name = src.name and tgt.family_name = src.family_name)
when matched then
update set tgt.bill = src.split_bill
where  tgt.bill != src.split_bill;