0

给定一个名为 CATEGORY 的表,其中包含列

  • 分类名称
  • CATEGORY_PARENT_NAME
  • 积极的

而这个查询

SELECT *
FROM CATEGORY
WHERE ACTIVE = 'TRUE'
START WITH CATEGORY_PARENT_NAME IS NULL   
CONNECT BY CATEGORY_PARENT_NAME = PRIOR CATEGORY_NAME   
ORDER SIBLINGS BY MENU_INDEX

我试图只获取其根父节点处于活动状态的活动子节点,但 oracle 也会返回非活动根的活动子节点,即使它们的父节点在 where 子句中被过滤。我做错了什么?

4

2 回答 2

2

您应该修改您的 START BY 子句以包含ACTIVE = TRUE,以便只考虑那些处于活动状态的根。

稍后将应用 WHERE 子句,以便您可以仅过滤掉 ACTIVE 子节点。

 select *
   from category
  where active = 'TRUE'
  start with category_parent_name is null
    and active = 'TRUE' 
connect by category_parent_name = prior category_name   
  order siblings by menu_index;
于 2013-09-20T04:01:23.050 回答
0

以下查询(请参阅SQL Fiddle)将为您提供其根处于活动状态的所有活动节点:

SELECT *
FROM (
  SELECT c.*,
    PRIOR c.ACTIVE AS PARENT_ACTIVE,
    CONNECT_BY_ROOT(c.CATEGORY_NAME) AS CATEGORY_ROOT_NAME,
    CONNECT_BY_ROOT(c.ACTIVE) AS ROOT_ACTIVE
  FROM CATEGORY c
  WHERE c.ACTIVE = 'TRUE'
  START WITH c.CATEGORY_PARENT_NAME IS NULL   
  CONNECT BY c.CATEGORY_PARENT_NAME = PRIOR c.CATEGORY_NAME   
  ORDER SIBLINGS BY c.MENU_INDEX
) a
WHERE a.ROOT_ACTIVE = 'TRUE'

要进一步过滤您的结果以仅包括其父节点、祖父节点和直到层次结构根的所有祖先节点都处于活动状态的活动节点(请参阅SQL Fiddle):

SELECT *
FROM (
  SELECT c.*,
    PRIOR c.ACTIVE AS PARENT_ACTIVE,
    CONNECT_BY_ROOT(c.CATEGORY_NAME) AS CATEGORY_ROOT_NAME,
    CONNECT_BY_ROOT(c.ACTIVE) AS ROOT_ACTIVE,
    SYS_CONNECT_BY_PATH(c.ACTIVE, '/') AS ACTIVE_PATH
  FROM CATEGORY c
  WHERE c.ACTIVE = 'TRUE'
  START WITH c.CATEGORY_PARENT_NAME IS NULL   
  CONNECT BY c.CATEGORY_PARENT_NAME = PRIOR c.CATEGORY_NAME   
  ORDER SIBLINGS BY c.MENU_INDEX
) a
WHERE a.ROOT_ACTIVE = 'TRUE'
  AND a.ACTIVE_PATH NOT LIKE '%FALSE%'

提示

  • 使用CONNECT_BY_ROOT运算符从根节点获取列值。
  • 使用PRIOR操作符从父节点获取列值(在根节点NULL时​​注意s)
  • 使用该SYS_CONNECT_BY_PATH函数获取一直到根节点的列值。
于 2013-08-08T22:52:53.967 回答