[英]Check 1:N hierarchy is maintained at 4 levels
我在表中有5個層次的層次結構數據
1.BRANCH
2.LEGAL-ENTITY
3.REPORT-UNIT
4.REGIONAL
5.COUNTRY
我有一個表,其中包含包含分支作為主鍵的所有層次結構的記錄。 我需要檢查在高層層次結構到低層層次結構之間是否維持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
您的第一個查詢是一個好的開始。 由於您沒有提供完整的表描述,因此我創建了自己的測試用例:
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才能提供與第一個查詢一樣多的信息!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.