У меня более новый SQLServer с базой данных с одной таблицей клиентов и одной таблицей со связями (родительские / дочерние отношения). Отношения могут быть разных типов (например, стандартная иерархия компании, друзья, конкуренция и т. Д.).
Я хочу перечислить полную иерархию компании (определенный тип отношений), начиная с одного клиента. Просто полный список, его не нужно заказывать, так как об этом позаботятся снаружи.
Я могу сделать это с помощью своего веб-скрипта, который создаст визуальную часть, но там может быть несколько огромных иерархий, и это приведет к выполнению сотен отдельных запросов. Это может занять слишком много времени.
Я пытался взглянуть на CTE (обычное табличное выражение), но не думаю, что действительно его понимаю. Кажется, я могу перечислить все, где мой начальный клиент является частью, но не там, где он вообще не является частью.
Таблица:
CREATE TABLE CUSTOMERS
(
id int not null,
name varchar(100) not null
);
CREATE TABLE RELATIONSHIPS
(
relationid int not null,
relationtype int not null,
customerid int not null,
parentid int not null
);
INSERT INTO CUSTOMERS(id,name) VALUES
(1040,'Cust A'),
(1041,'Cust B'),
(1042,'Cust C'),
(1043,'Cust D'),
(1044,'Cust E'),
(1045,'Cust F'),
(1046,'Cust G'),
(1047,'Cust H');
INSERT INTO RELATIONSHIPS(relationid,relationtype,customerid,parentid)
VALUES
(1,1,1041,1040),
(2,1,1042,1040),
(3,1,1043,1042),
(4,1,1047,1043),
(5,2,1041,1040);
Текущий SQL
with cte as (
select t.parentid,parent.name as parentname,t.customerid,child.name as childname
from RELATIONSHIPS t
INNER JOIN CUSTOMERS parent ON t.parentid = parent.id
INNER JOIN CUSTOMERS child ON t.customerid = child.id
where relationtype = 1 and (customerid = 1042 or parentid = 1042)
union all
select t.parentid,parent.name as parentname,t.customerid,child.name as childname
from RELATIONSHIPS t
INNER JOIN CUSTOMERS parent ON t.parentid = parent.id
INNER JOIN CUSTOMERS child ON t.customerid = child.id
inner join cte c on (c.customerid=t.parentid )
where relationtype = 1
)
select distinct t.* from cte t;
Скрипка: http://sqlfiddle.com/#!18/3e919b/14
Исходя из данных, приведенных выше, я хочу перечислить:
1040,Cust A,1041,Cust B
1040,Cust A,1042,Cust C
1042,Cust C,1041,Cust D
1043,Cust D,1047,Cust H
Мой запрос выше пытается перечислить все дерево иерархии, в которое входит клиент 1042 (Cust C). С моим запросом я, кажется, получаю все, кроме одного для ребенка 1041 (Cust B). Не уверен, как включить такие вещи в запрос, поскольку он не имеет прямого отношения к моей начинающей компании (за исключением того, что он находится в той же иерархии).