困难的分层查询和加入

时间:2011-03-01 21:37:39

标签: sql plsql oracle10g

(注意:这里的数据是一个组成的例子,因为我无法发布真实的数据。没有用的争论表结构没有意义或应该改变)

数据库是Oracle 10g。


给定:

Products
------------
ID
Price

Sample Data:
ID Product_ID Customer Quantity
-------------------------
1  30          2        10
2  40          2        15
3  50          5        7
4  60          5        9


Product_types
-----------
ID
Name
Parent
Type

Data
ID Product_ID  Name        Parent    
----------------------------------
1  10          Box                    
2  20          Toolbox     10      
3  30          Hammer      20     
4  40          Nail        30 


查询:

select * from (select * from Product_types t
START WITH t.Parent = 20
CONNECT BY PRIOR t.Product_ID = t.PARENT) t_result
left join Products p on T_RESULT.Product_ID = P.Product_ID
where P.Customer = 2;


当前输出:

Product_ID  Name      Parent     Product_ID_1   Customer   Quantity
-------------------------------------------------------------------
30          Hammer    20         30             2          10
40          Nail      30         40             2          15


期望的输出:

Product_ID  Name      Parent     Product_ID_1   Customer   Quantity
---------------------------------------------------------------------
20          Toolbox   10
30          Hammer    20         30               2          10
40          Nail      30         40               2          15


我发现由于我的where子句,它只选择customer = 2的行。但是,我想知道是否有任何方法可以获得层次结构的顶部。我的第一个想法是左连接应该仍然为工具箱行提供NULL客户,但不包括该行。我也试过了一个完整的外部联接。

我怀疑我可能需要运行两个查询并手动组合结果以获得我想要的结果,但我想先咨询一些专家。

任何人都可以想出一种获得所需输出的方法吗?

2 个答案:

答案 0 :(得分:3)

这有用吗?

select * from  
(select * from Product_types t
 START WITH T.Parent = 20 
 CONNECT BY PRIOR t.Product_ID = t.PARENT) t_result
left join Products p on T_RESULT.Product_ID = P.Product_ID
AND P.Customer = 2;

注意:我在最后一行将WHERE更改为AND以使条件成为外连接的一部分。

答案 1 :(得分:0)

此外,您应该更改递归的起点:

SELECT *
FROM (
  SELECT *
  FROM Product_types t
  START WITH t.Parent = 10 
  CONNECT BY PRIOR t.Product_ID = t.PARENT
) t_result
LEFT OUTER JOIN Products p 
  ON T_RESULT.Product_ID = P.Product_ID
  AND P.Customer = 2
;

甚至可以使用START WITH t.Parent IS NULL来获得完整的递归。