Tricky CTE-递归sql(编辑我的查询)

问题描述 投票:0回答:1

我想编辑我的查询以便获得更多点滴答声。

目标是获得每个客户的批准工作流,并以这种方式显示该信息:

客户| 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被分配给数学安德鲁... 308是表示Matt Andrew是一名客户

13被分配给John Connor ... 308是表明John Connor是客户的数字

因为数学安德鲁和约翰·康纳是客户(也称为客户),所以必须将他们链接到一个或多个批准者

一个客户可能有1个批准者,或2个批准者,或3个批准者或4个批准者,实体表中存在不同的批准者。

[当我说客户“可能”拥有1个或多个批准时,我的意思是:

CLIENT-APPROVER4(这是1-1的关系)PS:客户端将总是以某种方式与批准人4相关

客户-批准人1-批准人4(在这种情况下,将是2关系。一个:CLIENT-APPROVER1和另一个APPROVER1-APPROVER4)

客户端-批准人1-批准人2-批准人4(在这种情况下,3关系。一个:CLIENT-APPROVER1,APPROVER1- APPROVER2和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') 

客户端-审批者2:

(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');

APPROVER 1 -APPROVER 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');

这很重要:当客户链接到一个批准人时,在关系表中创建了RELATION。

表关系:

(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  |

这是我的小提琴:

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);

table new_table

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

和表relationships会像这样:

(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  |

我一直在尝试解决这个问题而没有成功。

您能帮我吗?

mysql sql common-table-expression recursive-query
1个回答
0
投票

我尝试过。并进行了标准化,增加了一个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 |批准人4:---------------- | :-------- | :-------- | :-------- | :--------MathAndrew-Chain1 |拉链| Ger | 3月|约翰MathAndrew-Chain2 |拉链| Ger | 3月|约翰

db <>小提琴here

© www.soinside.com 2019 - 2024. All rights reserved.