2014-11-05 3 views
0

У меня есть таблица sql, которая содержит список аффилиаций, где Entity A владеет Entity B, Entity B владеет Entity C и т. Д. У меня нет никакого текста sql для здесь, потому что я не уверен, с чего начать. Я считаю, что присоединение к таблице несколько раз не даст желаемых результатов, потому что это исключает определенные «присоединения».SQL - Создание связей между полями (Transitive relationship)

Что я хотел бы сделать, это группировать их с некоторым значением для тех объектов, которые связаны друг с другом (я агностик относительно того, какое значение используется для группировки). Это, вероятно, лучше всего объясняется в следующем примере.

Упрощение моей проблемы. У меня есть следующие две колонки в таблице. (Число в начале является информационным и просто представляет номер записи для того, чтобы помочь с моим описанием ниже.)

1 A | B 
2 Z | B 
3 Y | B 
4 B | C 
5 B | D 
6 D | E 
7 F | G 

Таким образом, A & B считается «связаны». Это также означает, что из-за "B", отображается в записях # 2,3,4 и 5, что Z, Y, C и D также связанных с A & B, таким образом:

A, B, C, D, Y и Z являются аффилированными.

Я также хочу, чтобы пойти на один шаг дальше, и видеть, что (RE: # 5), так как B & D аффилированы, что (RE: # 6) В и Е, также должны быть связаны. Таким образом, полный список принадлежность будет выглядеть примерно так:

A, B, C, D, E, Y и Z

Поскольку F & G появляются только в их принадлежности к каждому другие, они не были бы частью более крупной аффилированности, которую я только что описал. Поэтому я хочу, чтобы мои ожидаемые результаты, чтобы быть что-то вроде:

Entity | Grouping 
A | Group1 
B | Group1 
C | Group1 
D | Group1 
E | Group1 
Y | Group1 
Z | Group1 
F | Group2 
G | Group2 

Я сделал все возможное, чтобы объяснить это, так что мои извинения заранее за любое упущение деталей или запутанных/неполные объяснения.

Заранее благодарим за любую помощь!
Бест,
Robby

+0

Похоже, что вы хотите транзитивное отношение аффилированности. То есть, 'A | B' означает, что 'A' является аффилированным с' B', а 'B' связано с' A'. Это верно? Это актуально, потому что у Oracle есть функция «НАЧАТЬ С ... СОЕДИНЯТЬ ПРИОР ...» для выполнения иерархических запросов. Аналогичным образом SQL Server может обрабатывать рекурсию в так называемых общих табличных эксплозиях. Ни одна из этих функций не предполагает транзитивность, поэтому ее нужно будет добавить. –

+0

@OllieJones Спасибо за ваш комментарий. Да, это транзитивно, A | B равно B | A. Как бы вы добавили «транзитивность»? –

+0

Позвольте мне также добавить, как общий комментарий (и я понимаю, что это может быть слишком много из-за сложности), я хотел бы попытаться найти подход, который использует только более базовые объединения, поскольку я должен в конечном итоге преобразовать подход sql в более ограничительную часть программного обеспечения.У меня есть возможность разбить его на столько «шагов», сколько необходимо, когда будет установлен общий подход. –

ответ

0

Ну я не могу сказать что-нибудь для ORACLE, но вы могли бы управлять с рекурсивной КТР в SQL Server. Heres моего решения образца, он делает то, что вы просили при условии, что у вас есть таблица ведьму отображает отношение многого-ко-многим из одной таблицы в себе

DECLARE @testData table (EntityID int, EntityName varchar(1)) 
DECLARE @EntityRelations table (EntityID1 int, EntityID2 int) 

INSERT INTO @testData 
SELECT 1, 'A' 
UNION 
SELECT 2, 'B' 
UNION 
SELECT 3, 'C' 
UNION 
SELECT 4, 'D' 
UNION 
SELECT 5, 'E' 
UNION 
SELECT 6, 'F' 
UNION 
SELECT 7, 'G' 
UNION 
SELECT 8, 'Y' 
UNION 
SELECT 9, 'Z' 

INSERT INTO @EntityRelations 
SELECT 1, 2 
UNION 
SELECT 9, 2 
UNION 
SELECT 8, 2 
UNION 
SELECT 2, 3 
UNION 
SELECT 2, 4 
UNION 
SELECT 4, 5 
UNION 
SELECT 6, 7; 


WITH Affiliations (EntityID, Entity1Name, Entity2Name) AS 
(
    SELECT r.EntityID1 
      ,e.EntityName as Entity1Name 
      ,e2.EntityName as Entity2Name 
    FROM @EntityRelations r 
     JOIN @testData e ON e.EntityID = r.EntityID1 
     JOIN @testData e2 ON e2.EntityID = r.EntityID2 

    UNION ALL 

    SELECT r.EntityID1 
      ,e.EntityName as Entity1Name 
      ,e2.EntityName as Entity2Name 
    FROM @EntityRelations r 
     JOIN @testData e ON e.EntityID = r.EntityID1 
     JOIN @testData e2 ON e2.EntityID = r.EntityID2 
     JOIN Affiliations a ON a.EntityID = r.EntityID2 
) 

,AffiliationsReverse (EntityID, Entity1Name, Entity2Name) AS 
(
    SELECT r.EntityID2 
      ,e.EntityName as Entity1Name 
      ,e2.EntityName as Entity2Name 
    FROM @EntityRelations r 
     JOIN @testData e ON e.EntityID = r.EntityID1 
     JOIN @testData e2 ON e2.EntityID = r.EntityID2 

    UNION ALL 

    SELECT r.EntityID2 
      ,e.EntityName as Entity1Name 
      ,e2.EntityName as Entity2Name 
    FROM @EntityRelations r 
     JOIN @testData e ON e.EntityID = r.EntityID1 
     JOIN @testData e2 ON e2.EntityID = r.EntityID2 
     JOIN AffiliationsReverse a ON a.EntityID = r.EntityID1 
) 


SELECT DISTINCT EntityName 
FROM 
(
SELECT a.Entity1Name AS EntityName 
FROM Affiliations a 
    JOIN AffiliationsReverse ar ON ar.EntityID = a.EntityID 

UNION 

SELECT a.Entity2Name AS EntityName 
FROM Affiliations a 
    JOIN AffiliationsReverse ar ON ar.EntityID = a.EntityID 

UNION 

SELECT ar.Entity1Name AS EntityName 
FROM Affiliations a 
    JOIN AffiliationsReverse ar ON ar.EntityID = a.EntityID 

UNION 

SELECT ar.Entity2Name AS EntityName 
FROM Affiliations a 
    JOIN AffiliationsReverse ar ON ar.EntityID = a.EntityID 


) s 
Смежные вопросы