簡體   English   中英

棘手的 CTE - 遞歸 sql(編輯我的查詢)

[英]Tricky CTE - recursive sql (editing my query)

我想編輯我的查詢以獲得更棘手的東西。

目標是獲得每個客戶的批准工作流程,以這種方式顯示該信息:

客戶 | 批准人1 | 批准人2 | 批准人3 | 批准人4

以前,我有一個名為實體的表

(12, 'Math Andrew', 308, 'CHAIN1-MathAndrew')
(13, 'John Connor', 308, 'CHAIN2-JohnConnor')
(18, 'ZATCH', 309, null),
(19, 'MAX', 309, null),
(20, 'Ger',310, null),
(21, 'Mar',310, null),
(22, 'Maxwell',311, null),
(23, 'Ryan',312, null),
(24, 'Juy',313, null),
(25, 'Angel',314, null),
(26, 'John',315, null);

請注意:

12 被分配給 Math Andrew... 308 是表示 Matt Andrew 是客戶的數字

13 被分配給約翰康納...... 308 是表示約翰康納是客戶的數字

因為 Math Andrew 和 John Connor 是 CLIENTS(也稱為 CUSTOMERS),所以他們必須與一個或多個 APPROVERS 相關聯

一個客戶可以有 1 個批准者,或 2 個批准者或 3 個批准者或 4 個批准者,實體表中存在不同的批准者。

當我說一個客戶“可以”擁有 1 個或多個 APPROVERS 時,我的意思是:

客戶 - APPROVER4(這是 1-1 關系) PS:客戶將始終以某種方式與 APPROVER4 相關

CLIENT - APPROVER1 - APPROVER4(在這種情況下將有 2 個關系。一個:CLIENT-APPROVER1 和另一個 APPROVER1-APPROVER4)

CLIENT - APPROVER1 - APPROVER2 - APPROVER4(在這種情況下將有 3 個關系。一個:CLIENT-APPROVER1、APPROVER1- APPROVER2 和 APPROVER2 - APPROVER4)

等等......(希望你能明白)

表類型_實體

(308,'CLIENT'),
(309,'APPROVER1'),
(310,'APPROVER2'),
(311,'APPROVER3'),
(312,'J3 APPROVER4'),
(313,'J4 APPROVER4'),
(314,'J5 APPROVER4'),
(315, 'J6 APPROVER4'),
(316,'J7 APPROVER4');

表類型_關系

(444,'J6 CLIENT-APPROVER4'),
(445,'J3 CLIENT-APPROVER4'),
(446,'J4 CLIENT-APPROVER4'),
(447,'J10 CLIENT-APPROVER4'),
(449,'J5 CLIENT-APPROVER4'),
(453,'J5 CLIENT-APPROVER4'),
(456,'J7 CLIENT-APPROVER4'),
(457,'J8 CLIENT-APPROVER4'),
(458,'CLIENT-APPROVER3'),
(459,'CLIENT-APPROVER1'),
(460,'APPROVER1-APPROVER2'),
(461,'APPROVER1-APPROVER3'),
(462,'J3 APPROVER1-APPROVER4'),
(463,'APPROVER2-APPROVER3'),
(464,'J3 APPROVER3-APPROVER4'),
(465,'J4 APPROVER3-APPROVER4'),
(466,'J5 APPROVER3-APPROVER4'),
(467,'J6 APPROVER3-APPROVER4'),
(468,'J7 APPROVER3-APPROVER4'),
(469,'J8 APPROVER3-APPROVER4'),
(470,'J10 APPROVER3-APPROVER4'),
(471,'CLIENT-APPROVER2');

關系類型:

客戶 - 批准人 1 :

(459,'CLIENT-APPROVER1') 

客戶 - APPROVER2 :

(471,'CLIENT-APPROVER2') 

客戶 - 批准人 3 :

(461,'APPROVER1-APPROVER3')

客戶 - 批准人 4:

(445,'J3 CLIENT-APPROVER4'),
(446,'J4 CLIENT-APPROVER4'),
(449,'J5 CLIENT-APPROVER4'),
(444,'J6 CLIENT-APPROVER4'),
(456,'J7 CLIENT-APPROVER4'),
(457,'J8 CLIENT-APPROVER4'),
(447,'J10 CLIENT-APPROVER4');

審批人 1 - 審批人 2:

(460,'APPROVER1-APPROVER2')

審批人 2 - 審批人 3:

(463,'APPROVER2-APPROVER3')

審批人 3 - 審批人 4:

(464,'J3 APPROVER3-APPROVER4'),
(465,'J4 APPROVER3-APPROVER4'),
(466,'J5 APPROVER3-APPROVER4'),
(467,'J6 APPROVER3-APPROVER4'),
(468,'J7 APPROVER3-APPROVER4'),
(469,'J8 APPROVER3-APPROVER4'),
(470,'J10 APPROVER3-APPROVER4');

這很重要:當客戶鏈接到一個審批者時,會在關系表中創建新關系。

表關系:

(787,459,12,18),
(788,460,18,20),
(789,463,20,21),
(790,467,21,26);

787 是創建該行時分配的編號

459 代表關系:客戶 - 審批人

12 CHAIN1-MathAndre 是客戶端

18 是審批人

遵循這個想法:

APPROVER1 與 APPROVER2 相關聯:

(788,460,18,20)

APPROVER2 與 APPROVER3 相關聯:

(789,463,20,21)

APPROVER3 與 APPROVER4 相關聯:

(790,467,21,26) ​

所以,我在屏幕上顯示這個:

|CLIENT               | APPROVER1 | APPROVER2 | APPROVER3 | APPROVER4|
|CHAIN1-MathAndrew    |   ZATCH   |   Ger     |    Mar    |    John  |
|CHAIN2-JohnConnor    |    MAX    |           |    Mario  |    Steven|
|CHAIN3-MarioShapiro  |    IVAN   |           |           |    John  |

這是我的小提琴:

小提琴

這是我的查詢:

WITH recursive relationships_CTE as (
  select e.id, e.description AS name, 1 col_id, 
    row_number() over (order by e.id) row_id
  from entities e
  where e.description like 'CHAIN%'
    UNION ALL
  select r.description_entitiy_2, e.name, col_id+ 1, row_id
  from relationships_CTE cte
  left join relationships r
    on r.description_entitiy_1 = cte.id
  join entities e 
    on r.description_entitiy_2 = e.id
)
select 
  max(case when col_id = 1 then name end) client,
  max(case when col_id = 2 then name end) approver1,
  max(case when col_id = 3 then name end) approver2,
  max(case when col_id = 4 then name end) approver3,
  max(case when col_id = 5 then name end) approver4
from relationships_CTE
group by row_id

現在,這就是我想要做的:

假設我有一個名為 new_table 的新表,並且我稍微修改了表實體:

(12, 'Math Andrew', 308, 45)
(13, 'John Connor', 308, 46)
(18, 'ZATCH', 309, null),
(19, 'MAX', 309, null),
(20, 'Ger',310, null),
(21, 'Mar',310, null),
(22, 'Maxwell',311, null),
(23, 'Ryan',312, null),
(24, 'Juy',313, null),
(25, 'Angel',314, null),
(26, 'John',315, null);

表新表

(45,'Math Andrew', 'Chain1')
(45,'Math Andrew', 'Chain2')
(46, 'John Connor', 'Chain1')
(46, ''John Connor', 'Chain2')

關系是這樣的:

(787,459,'45-Chain1',18)
(788,460,18,20)
(789,463,20,21)
(790,467,21,26)

因此,我想將表實體與表new_table連接起來,獲取關系 45-Chain1,然后在表關系中找到 45-Chain1 並獲得類似的結果(並對所有不同的客戶端執行相同操作):

|CLIENT               | APPROVER1 | APPROVER2 | APPROVER3 | APPROVER4|
|45-Chain1            |   ZATCH   |   Ger     |    Mar    |    John  |

我一直在嘗試解決這個問題,但沒有成功。

請你幫助我好嗎?

我試過。
並規范化了一點,添加了一個chains

這是我的嘗試:

 create table entity_types ( entity_type_id int primary key, entity_type_name varchar(32) not null );
\n \n
create table relation_types ( relation_type_id int primary key, relation_type_name varchar(32) not null );
\n \n
create table chains ( chain_id int primary key, chain_name varchar(30) not null );
\n \n
create table entities ( entity_id int primary key, entity_name varchar(32) not null, entity_type_id int not null, chain_id int, foreign key (entity_type_id) references entity_types(entity_type_id), foreign key (chain_id) references chains(chain_id) );
\n \n
create table relationships ( relationship_id int primary key, relation_type_id int not null, entity_id_1 int not null, entity_id_2 int not null, foreign key (relation_type_id) references relation_types(relation_type_id) );
\n \n
create table entity_chains ( entity_id int not null, chain_id int not null, primary key (entity_id, chain_id), foreign key (chain_id) references chains(chain_id), foreign key (entity_id) references entities(entity_id) );
\n \n
INSERT INTO entity_types (entity_type_id, entity_type_name) VALUES (308,'CLIENT'), (309,'APPROVER1'), (310,'APPROVER2'), (311,'APPROVER3'), (312,'J3 APPROVER4'), (313,'J4 APPROVER4'), (314,'J5 APPROVER4'), (315,'J6 APPROVER4'), (316,'J7 APPROVER4');
\n \n
INSERT INTO relation_types (relation_type_id, relation_type_name) VALUES (444,'J6 CLIENT-APPROVER4'), (445,'J3 CLIENT-APPROVER4'), (446,'J4 CLIENT-APPROVER4'), (447,'J10 CLIENT-APPROVER4'), (448,'J4 CLIENT-APPROVER4'), (449,'J5 CLIENT-APPROVER4'), (450,'J10 CLIENT-APPROVER4'), (451,'J3 CLIENT-APPROVER4'), (452,'J8 CLIENT-APPROVER4'), (453,'J5 CLIENT-APPROVER4'), (454,'J6 CLIENT-APPROVER4'), (455,'J7 CLIENT-APPROVER4'), (456,'J7 CLIENT-APPROVER4'), (457,'J8 CLIENT-APPROVER4'), (458,'CLIENT-APPROVER3'), (459,'CLIENT-APPROVER1'), (460,'APPROVER1-APPROVER2'), (461,'APPROVER1-APPROVER3'), (462,'J3 APPROVER1-APPROVER4'), (463,'APPROVER2-APPROVER3'), (464,'J3 APPROVER3-APPROVER4'), (465,'J4 APPROVER3-APPROVER4'), (466,'J5 APPROVER3-APPROVER4'), (467,'J6 APPROVER3-APPROVER4'), (468,'J7 APPROVER3-APPROVER4'), (469,'J8 APPROVER3-APPROVER4'), (470,'J10 APPROVER3-APPROVER4'), (471,'CLIENT-APPROVER2');
\n \n
insert into chains (chain_id, chain_name) values (45,'Chain1'), (46,'Chain2');
\n \n
INSERT INTO entities (entity_id, entity_name, entity_type_id, chain_id) VALUES (12, 'Math Andrew', 308, 45), (13, 'John Connor', 308, 46), (18, 'ZATCH', 309, null), (19, 'MAX', 309, null), (20, 'Ger',310, null), (21, 'Mar',310, null), (22, 'Maxwell',311, null), (23, 'Ryan',312, null), (24, 'Juy',313, null), (25, 'Angel',314, null), (26, 'John',315, null);
\n \n
INSERT INTO relationships (relationship_id, relation_type_id, entity_id_1, entity_id_2) VALUES (787,459,12,18), (788,460,18,20), (789,463,20,21), (790,467,21,26);
\n \n
insert into entity_chains (entity_id, chain_id) values (12, 45), (12, 46), (13, 45), (13, 46);
\n \n
WITH RECURSIVE RCTE AS ( SELECT ent.chain_id, entch.entity_id as entity_id_0, 0 as lvl, 0 as entity_id_1, entch.entity_id as entity_id_2, 0 as relation_type_id FROM entities ent JOIN entity_chains entch ON entch.chain_id = ent.chain_id UNION ALL SELECT cte.chain_id, cte.entity_id_0, lvl+1, rel.entity_id_1, rel.entity_id_2, rel.relation_type_id FROM RCTE cte JOIN relationships rel ON rel.entity_id_1 = cte.entity_id_2 ), CTE AS ( SELECT rcte.*, chains.chain_name, ent0.entity_name as entity_name_0, -- reltype.relation_type_name, -- enttype2.entity_type_name as entity_type_name_2, -- ent1.entity_name as entity_name_1, ent2.entity_name as entity_name_2 FROM RCTE rcte JOIN chains ON chains.chain_id = rcte.chain_id JOIN entities ent0 ON ent0.entity_id = rcte.entity_id_0 JOIN entities ent2 ON ent2.entity_id = rcte.entity_id_2 -- LEFT JOIN entity_types enttype2 ON enttype2.entity_type_id = ent2.entity_type_id -- LEFT JOIN relation_types reltype ON reltype.relation_type_id = rcte.relation_type_id -- LEFT JOIN entities ent1 ON ent1.entity_id = rcte.entity_id_1 ) /* SELECT * FROM CTE WHERE lvl > 0 ORDER BY chain_name, entity_id_0, lvl; */ SELECT REPLACE(CONCAT(entity_name_0,'-',chain_name),' ','') as chain_client, max(case when lvl=1 then entity_name_2 end) as approver1, max(case when lvl=2 then entity_name_2 end) as approver2, max(case when lvl=3 then entity_name_2 end) as approver3, max(case when lvl=4 then entity_name_2 end) as approver4 FROM CTE cte WHERE lvl > 0 GROUP BY chain_name, entity_name_0 ORDER BY chain_client;
\n chain_client | 審批人1 | 批准人2 | 批准人3 | 批准人4\n :---------------- |  :-------- |  :-------- |  :-------- |  :--------\n MathAndrew-Chain1 | 扎奇 | 格爾 | 三月 | 約翰     \n MathAndrew-Chain2 | 扎奇 | 格爾 | 三月 | 約翰     \n

db<> 在這里擺弄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM