Как мне получить список корпораций, в которых указана корпорация (ID)? - PullRequest
0 голосов
/ 05 августа 2020

ВАЖНО ... в моем проекте RL идентификатор не INT, а GUID, поэтому мои данные НЕ иерархичны!

У меня есть таблица с компаниями и таблица со связями между компаниями.

Мне нужно получить список компаний по указанному c идентификатору компании.

Вот мой тестовый код ...

CREATE TABLE ##corporations
(  
    CorporationID INT NOT NULL,  
    CorporationName NVARCHAR(20) NOT NULL
);  

CREATE TABLE ##corporationLinks
(  
    FromCorporationID INT NOT NULL,  
    ToCorporationID INT NOT NULL
);  

INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (1, 'Nike')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (2, 'Cocal Cola')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (3, 'Apple')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (4, 'Google')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (5, 'Amazon')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (6, 'Samsung')

INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (1, 2)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (2, 3)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (4, 5)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (4, 6)

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 2 OR ToCorporationID = 2

/** 

Organisations (##corporationLinks) are...

Nike + Coca Cola + Apple + Marcy

and...

Google + Amazon + Samsung

**/

-- How do I eg get a list of companies where Coca Cola is in ... that is where FromCorporationID = 2 OR ToCorporationID = 2 ... result should be Nike, Coca Cola and Apple?
-- How do I eg get a list of companies where Samsung is in ... that is where FromCorporationID = 6 OR ToCorporationID = 6 ... result should be Google, Amazon Cola and Samsung?

DROP TABLE ##corporationLinks 
DROP TABLE ##corporations

UDPATE:

Если мне нужно найти корпорации, в которые входит Coca Cola, я бы взялся за дело ...

SELECT * FROM ## corporationLinks ГДЕ FromCorporationID = 2 ИЛИ ToCorporationID = 2

Тогда я получу 2 результата ...

FromCorporationID   ToCorporationID
-----------------------------------
1                   2
2                   3

Здесь после того, как мне нужно посмотреть, в каких корпорациях результат является частью ...

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 1 OR ToCorporationID = 1

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 3 OR ToCorporationID = 3

Тогда я получу еще одну корпорацию (7):

FromCorporationID   ToCorporationID
-----------------------------------
3                   7

И затем мне нужно погрузиться в то, какие корпорации связаны с 7 ...

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 7 OR ToCorporationID = 7

И погрузитесь в этот результат (думаю, он называется рекурсивным). et c.

ОБНОВЛЕНИЕ 2:

Я обновил свой образец выше, чтобы добавить еще одну компанию, которая должна быть возвращена, если поиск ведется по Coca Cola.

Ожидаемый результат из запроса (Coca Cola) выше:

CorporationID:
--------------
2
1
3
7

Ответы [ 3 ]

0 голосов
/ 05 августа 2020

С рекурсивным CTE:

with 
  root as (select CorporationID id from companies where CorporationName = 'Coca Cola'),
  cte as (
    select 
      case when r.id = cl.FromCorporationID then cl.ToCorporationID else cl.FromCorporationID end id,
      case when r.id = cl.FromCorporationID then cl.FromCorporationID else cl.ToCorporationID end otherid      
    from corporationLinks cl inner join root r
    on r.id in (cl.FromCorporationID, cl.ToCorporationID)
    union all
    select 
      case when c.id = cl.FromCorporationID then cl.ToCorporationID else cl.FromCorporationID end id,
      case when c.id = cl.FromCorporationID then cl.FromCorporationID else cl.ToCorporationID end otherid            
    from corporationLinks cl inner join cte c
    on c.id in (cl.FromCorporationID, cl.ToCorporationID)
    and c.otherid not in (cl.FromCorporationID, cl.ToCorporationID)
  )
select id CorporationID from root
union all
select id from cte

См. демонстрацию . Результатов:

> | CorporationID |
> | ------------: |
> |             2 |
> |             1 |
> |             3 |
> |             7 |
0 голосов
/ 05 августа 2020

Просто используйте рекурсивный CTE

WITH cte
AS
(
    SELECT l1.FromCorporationID,l1.ToCorporationID
    FROM ##corporationLinks l1
    UNION ALL
    SELECT cte.FromCorporationID,l3.ToCorporationID
    FROM ##corporationLinks l3
    JOIN cte 
        ON cte.ToCorporationID = l3.FromCorporationID

)

SELECT cte.ToCorporationID--parent
FROM cte
WHERE cte.FromCorporationID =2
UNION
SELECT cte.FromCorporationID--child
FROM cte
WHERE cte.ToCorporationID =2
UNION
SELECT c.CorporationID--self
FROM ##corporations c
WHERE c.CorporationID = 2
0 голосов
/ 05 августа 2020

слева присоединитесь к ## компаниям, укажите ее CorporationID или вы можете включить название компании в запрос, а затем сгруппировать по CorporationID, вы должны увидеть, какой компании она принадлежит

...