检查1:N层次结构维持在4个级别

时间:2015-04-02 07:17:09

标签: sql plsql hana

我在表格中有5个级别的层次结构数据

1.BRANCH
2.LEGAL-ENTITY
3.REPORT-UNIT
4.REGIONAL
5.COUNTRY

我有一个表,其中包含包含所有层次结构的记录,其中Branch作为主键。 我需要检查1:n的关系是否在较高级别层次结构与较低级别层次结构之间保持不变。

WHITEFIELD|BANGALORE|KARNATAKA|INDIA|APAC
WHITEFIELD|BANGALORE|MYSORE|INDIA|APAC - WRONG RECORD
MG ROAD|BANGALORE|KARNATAKA|INDIA|APAC
MG ROAD|NEW DELHI|DELHI|INDIA|APAC - WRONG RECORD
SILK BOARD|BANGALORE|KARNATAKA|INDIA|APAC
SILK BOARD|PUNE|MAHARASTRA|INDIA|APAC - WRONG RECORD

为实现这一点,我想写一个查询,它可以给我不满足上述规则的记录。

我已经编写了一个查询,可以给出第4和第5级的结果。

SELECT COD_BRNC,COUNT(DISTINCT COD_LEGL_ENTT) FROM TDI_GEO_BY_ORIGIN
WHERE COD_BRNC  NOT LIKE '%_D' AND YEAR(DAT_END_GEO_ORGN ) = 9999
GROUP BY COD_BRNC HAVING COUNT(DISTINCT COD_LEGL_ENTT) >  1

它给了我

SILK BOARD|2
MG ROAD|2

1 个答案:

答案 0 :(得分:0)

您的第一个查询是一个好的开始。 由于您没有提供完整的表格描述,因此我创建了自己的测试用例:

DROP TABLE level_5_test;

CREATE TABLE level_5_test( branch_id    VARCHAR2( 3 )
                     , level_1      VARCHAR2( 3 )
                     , level_2      VARCHAR2( 3 )
                     , level_3      VARCHAR2( 3 )
                     , level_4      VARCHAR2( 3 )
                     , description  VARCHAR2( 30 )
                      );

INSERT INTO level_5_test
 VALUES ( 'B0', 'L1', 'L2', 'L3', 'L4', 'No Problems' );

INSERT INTO level_5_test
 VALUES ( 'B1', 'L1', 'L2', 'L3', 'L4', 'Level 1 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B1', 'E1', 'L2', 'L3', 'L4', 'Level 1 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B2', 'L1', 'L2', 'L3', 'L4', 'Level 2 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B2', 'L1', 'E2', 'L3', 'L4', 'Level 2 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B3', 'L1', 'L2', 'L3', 'L4', 'Level 3 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B3', 'L1', 'L2', 'E3', 'L4', 'Level 3 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B4', 'L1', 'L2', 'L3', 'L4', 'Level 4 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B4', 'L1', 'L2', 'L3', 'E4', 'Level 4 Problems' );

INSERT INTO level_5_test
     VALUES ( 'B5', 'L1', 'L2', 'L3', 'E4', 'Double Problems' );

INSERT INTO level_5_test
     VALUES ( 'B5', 'L1', 'E2', 'L3', 'L4', 'Double Problems' );

COMMIT;
--

获得所有答案的最佳方法是查询所有字段并添加count(distinct ...)的分析变体,其中您通过branch_id进行分区:

WITH level_query
     AS (SELECT branch_id
              , level_1
              , level_2
              , level_3
              , level_4
              , description
              , COUNT( DISTINCT level_1 ) OVER (PARTITION BY branch_id)
                   AS level_1_count
              , COUNT( DISTINCT level_2 ) OVER (PARTITION BY branch_id)
                   AS level_2_count
              , COUNT( DISTINCT level_3 ) OVER (PARTITION BY branch_id)
                   AS level_3_count
              , COUNT( DISTINCT level_4 ) OVER (PARTITION BY branch_id)
               AS level_4_count
       FROM level_5_test)
SELECT *
  FROM level_query
 WHERE level_1_count > 1
    OR level_2_count > 1
    OR level_3_count > 1
    OR level_4_count > 1;

这适用于Oracle,但对Hana可能不起作用。然后,您必须将四个查询与UNION ALL

组合在一起
SELECT   'L1' AS level_name
       , branch_id
    FROM level_5_test
GROUP BY branch_id
  HAVING COUNT( DISTINCT level_1 ) > 1
UNION ALL
SELECT   'L2' AS level_name
       , branch_id
    FROM level_5_test
GROUP BY branch_id
  HAVING COUNT( DISTINCT level_2 ) > 1
UNION ALL
SELECT   'L3' AS level_name
       , branch_id
    FROM level_5_test
GROUP BY branch_id
  HAVING COUNT( DISTINCT level_3 ) > 1
UNION ALL
SELECT   'L4' AS level_name
       , branch_id
    FROM level_5_test
GROUP BY branch_id
  HAVING COUNT( DISTINCT level_4 ) > 1
ORDER BY 2, 1;

第一个解决方案只需要一个全表扫描,第二个查询需要四个,并且需要第五个FTS来提供与第一个一样多的信息!