如何使用oracle查询获得此结果

时间:2014-07-19 08:43:33

标签: sql oracle

首先,通过一个抵押品,您可以从银行多次借钱。这意味着一个collat​​eral_num有很多loan_num。

其次,您可以为一笔贷款提供许多抵押品。这意味着一个loan_num有很多collat​​eral_num。

这样的表名为LOAN。

collateral_num | loan_num
-------------------------
 C1            |  A5
 C2            |  A5
 C2            |  A1
 C3            |  A1
 C3            |  A3
 C6            |  A7
 C7            |  A7

我想从LOAN获得最小的collat​​eral_num,如下表所示。 我将解释minium clooateral_num。 第一个表中有两个组。其中一个是从第一排到第五排。然后,我们可以在第一组中找到一些关系,如C1→a5→c2→a1→c3→a3。 我们丢弃包括' a'在内的节点。 因此,c1将是c1 c2 c3中的最小聚集数。(因为c1的编号最小。)

在第二组(c6→a7→c7)中,最小聚合数将为c6。

collateral_num | minimum_collateral_num | loan_num
--------------------------------------------------
 C1            |   C1                   |    A5
 C2            |   C1                   |    A5
 C2            |   C1                   |    A1
 C3            |   C1                   |    A1
 C3            |   C1                   |    A3
 C6            |   C6                   |    A7
 C7            |   C6                   |    A7

如何进行SQL查询以获得结果我已经说过了。任何评论对我都有帮助。感谢。

2 个答案:

答案 0 :(得分:0)

当我遇到这个问题时,我已经使用重复更新完成了工作。首先创建一个包含三列的表,即附属标识,加载标识和组标识。然后,它重复将抵押品设置为抵押品或负荷ID相同的最低贷款额:

create table clgrp as
    select collateral_id, loan_id,
           min(load_id) over (partition by collateral_id) as grp
    from loans;

然后反复进行此更新:

update clgrp
    set grp = least((select min(grp)
                     from clgrp join
                          loans
                          on clgrp.collateral_id = loans.collateral_id
                    ),
                    (select min(grp)
                     from clgrp join
                          loans
                          on clgrp.load_id = loans.loan
                    )
                   );

然后重复此过程直到没有行更改。

答案 1 :(得分:0)

这不是SQL中最优雅的部分,但它确实产生了正确的结果。

有几个子查询;使用子查询因子分解语法,我们可以将它们组合在一起,这样一个结果集就可以作为后续查询的输入。

CTE0只查询基表,所以我们只执行一次。

CTE1识别通过贷款挂钩的所有抵押品。

CTE2会过滤最低抵押品数量。

CTE3使用Oracle的分层查询语法来设置最小(根)抵押品数量。

CTE_FIN(最后一个!)使用分析LAG()来填充空根。

完成了所有我们加入最后一个子查询与第​​一个子查询,以获得贷款 - 和叶节点抵押品。 UNION有必要拿起那些一个抵押品只针对一个且只有一个贷款的情况(我将其添加为a case in SQL Fiddle)。

with cte0 as ( select collateral_num, loan_num from loan )
      , cte1 as (
              select c1.collateral_num as cp
                     , c2.collateral_num as cc
                     , c1.loan_num
               from cte0 c1
                   join cte0 c2
                       on c1.loan_num = c2.loan_num
               where c1.collateral_num < c2.collateral_num )
   , cte2 as ( select cp from cte1
               minus
               select cc from cte1 )
    , cte3 as ( select cte1.cp
                     , cte1.cc
                     , case when cte1.cp = cte2.cp then cte2.cp end as rt
             from cte1
                  left join cte2
                   on cte1.cp = cte2.cp )
    , cte_fin as (
        select cte3.cp
               , cte3.cc
               , nvl(lag(cte3.rt) over (ORDER BY cte3.cp ), cte3.rt) as rt
        from cte3
        connect by prior cte3.cc = cte3.cp
        start with cte3.rt is not null )
select cte0.collateral_num
       , cte0.loan_num
       , cte_fin.rt as min_collateral_num
from cte_fin
     cross join cte0
where cte0.collateral_num = cte_fin.cp
or cte0.collateral_num = cte_fin.cc
union
select cte0.collateral_num
       , cte0.loan_num
       , cte0.collateral_num
from  cte0
where cte0.collateral_num not in (select cp from cte1)
and   cte0.collateral_num not in (select cc from cte1)
order by 3 , 1
/

正如小提琴所示,此查询适用于提供的示例数据。我不保证它在现实生活中如何工作,并提供真实的数据集。我认为很容易找到破坏这些代码的贷款和抵押品链。这样做是留给读者的练习:)