Oracle中的分层SQL查询

时间:2013-12-10 21:10:28

标签: sql oracle

我有一个问题,我希望你可以提供帮助。我一直试图想出一种以我正在寻找的方式显示数据的方法,但没有取得多大成功。基本上,数据的布局如下:

数据示例:


UID | Name | Action | Parent_UID | Date         |  Category    |    Item
1   | John | Delete | (null)     | 10-DEC-2013  |    Cars      |    Cars
2   | John | Delete | 1          | 10-DEC-2013  |    Cars      |    Ford
3   | Mark | Add    | (null)     | 09-DEC-2013  |    Cars      |    Tesla
4   | Mark | Add    | 3          | 09-DEC-2013  |    Model     |    Model-S
5   | Mark | Add    | 4          | 09-DEC-2013  |   Inventory  |      5

该表包含父记录以及记录所采取操作的子记录。 Parent记录的Parent_UID为null。此表中有许多记录,默认情况下它们没有以任何方式组织。如您所见,该表可以在数据层方面变得非常深。

我想做的是首先拥有父记录,然后是子记录。

我在Oracle数据库中尝试了以下SQL:

select * from Table where Date > '09-DEC-2013' and Name = 'John' start with parent_uid is null connect by parent_uid = uid;

但它需要永远运行,我不确定语法是否正确。有没有更好的方法来获得我正在寻找的东西?

3 个答案:

答案 0 :(得分:0)

我认为你需要改变你的连接 CONNID BY UID = PRIOR PARENT_UID

还检查索引是否存在 对于这些领域。一个在uud + parent_uid上 应该做的伎俩

另外,为了显示结果中的层次结构,您可以使用 选择列表中的级别将显示深度。

答案 1 :(得分:0)

您忘记了PRIOR中的CONNECT BY

SELECT *
-- don't name your table 'table'
FROM my_table  
-- don't name your column 'date'
-- also, use explicit conversion to a date
WHERE my_date > TO_DATE('09-12-2013', 'DD-MM-YYYY')  
  AND name = 'John'
START WITH parent_id IS NULL 
-- you want the parent id to be equal to the PRIOR id
-- also, don't name your column uid
CONNECT BY parent_id = PRIOR id; 

答案 2 :(得分:0)

有一些问题:

  • UID是一个唯一标识会话用户的系统函数 - 如果要将其用作列名,则必须将其括在双引号中"";
  • DATE是一种数据类型,是reserved word - 与上面相同,如果要调用列Date,则需要用双引号括起来;和
  • 您需要将parent_UIDPRIOR "UID"
  • 相关联

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE tbl ( "UID", Name, Action, Parent_UID, "Date", Category, Item ) AS
          SELECT 1, 'John', 'Delete', null, TO_DATE( '10-DEC-2013', 'DD-MON-YYYY' ), 'Cars',      'Cars' FROM DUAL
UNION ALL SELECT 2, 'John', 'Delete', 1,    TO_DATE( '10-DEC-2013', 'DD-MON-YYYY' ), 'Cars',      'Ford' FROM DUAL
UNION ALL SELECT 3, 'Mark', 'Add',    null, TO_DATE( '09-DEC-2013', 'DD-MON-YYYY' ), 'Cars',      'Tesla' FROM DUAL
UNION ALL SELECT 4, 'Mark', 'Add',    3,    TO_DATE( '09-DEC-2013', 'DD-MON-YYYY' ), 'Model',     'Model-S' FROM DUAL
UNION ALL SELECT 5, 'Mark', 'Add',    4,    TO_DATE( '09-DEC-2013', 'DD-MON-YYYY' ), 'Inventory', '5' FROM DUAL;

查询1

SELECT *
FROM   tbl
WHERE  "Date" >= TO_DATE( '09-DEC-2013', 'DD-MON-YYYY' )
AND    Name = 'John'
START WITH parent_UID IS NULL
CONNECT BY PRIOR "UID" = parent_uid
ORDER SIBLINGS BY "UID"

<强> Results

| UID | NAME | ACTION | PARENT_UID |                            DATE | CATEGORY | ITEM |
|-----|------|--------|------------|---------------------------------|----------|------|
|   1 | John | Delete |     (null) | December, 10 2013 00:00:00+0000 |     Cars | Cars |
|   2 | John | Delete |          1 | December, 10 2013 00:00:00+0000 |     Cars | Ford |