我想编辑我的查询以获得更棘手的内容。
目标是获得每个客户的审批工作流程,并以这种方式显示该信息:
CLIENT | APPROVER1 | APPROVER2 | APPROVER3 | APPROVER4
以前,我有一个名为实体的表
(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 was assigned to Math Andrew... 308 is the number that says that Matt Andrew is a CLIENT
13 was assigned to John Connor... 308 is the number that says that John Connor is a CLIENT
因为 Math Andrew 和 John Connor 是客户(也称为客户),所以他们必须链接到一个或多个批准者
一个客户端可以有 1 个 APPROVER、OR 2 APPROVERS、3 个 APPROVERS 或 4 个 APPROVER,实体表中存在不同的审批人。
当我说客户“可以拥有”1 个或更多批准者时,我的意思是:
CLIENT - APPROVER4 (this is a 1-1 relationship) PS: A CLIENT WILL ALWAYS BE RELATED TO the APPROVER4 IN SOME WAY OR ANOTHER
CLIENT - APPROVER1 - APPROVER4 (in this case there Will be 2 relations.. ONE: CLIENT-APPROVER1 and another APPROVER1-APPROVER4)
CLIENT - APPROVER1 - APPROVER2 - APPROVER4 (in this case there Will be 3 relations.. ONE: CLIENT-APPROVER1, APPROVER1- APPROVER2 AND APPROVER2 - APPROVER4)
等等...(希望您明白)
表 type_entities
(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')
客户 - APPROVER3:
(461,'APPROVER1-APPROVER3')
客户 - APPROVER4:
(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');
<小时/>
THIS IS IMPORTANT: when a client is linked to one approver, a NEW RELATION is created inside relationships table.
表关系:
(787,459,12,18),
(788,460,18,20),
(789,463,20,21),
(790,467,21,26);
787 IS THE NUMBER THAT WAS ASSIGNED WHEN THAT ROW WAS CREATED
459 REPRESENTS THE RELATION: CLIENT - APPROVER
12 CHAIN1-MathAndre is the client
18 is the approver
遵循这个想法:
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 |
这是我的 fiddle :
这是我的查询:
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);
表 new_table
(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)
所以,我想将表 entities 与表 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 );
✓
create table relation_types ( relation_type_id int primary key, relation_type_name varchar(32) not null );
✓
create table chains ( chain_id int primary key, chain_name varchar(30) not null );
✓
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) );
✓
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) );
✓
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) );
✓
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');
✓
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');
✓
insert into chains (chain_id, chain_name) values (45,'Chain1'), (46,'Chain2');
✓
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);
✓
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);
✓
insert into entity_chains (entity_id, chain_id) values (12, 45), (12, 46), (13, 45), (13, 46);
✓
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;
chain_client | approver1 | approver2 | approver3 | approver4 :---------------- | :-------- | :-------- | :-------- | :-------- MathAndrew-Chain1 | ZATCH | Ger | Mar | John MathAndrew-Chain2 | ZATCH | Ger | Mar | John
db<> fiddle here
关于mysql - 棘手的 CTE - 递归 sql(编辑我的查询),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59021115/