2016-05-02 2 views
0

У меня есть две таблицы «TestItem» и «Connector», где Connector используется для связывания двух элементов в «TestItem». У меня есть два вопроса в приоритетном порядке. Но, во-первых, не стесняйтесь предлагать альтернативные подходы. Я открыт для предложения полностью переосмыслить мой подход к тому, чего я хочу достичь здесь.SQL соединяется в оба способа с одним результатом

Вопрос 1) Как получить отношения в обоих направлениях вернулись в тот же результат

Вопрос 2) Как выбирать наиболее эффективный способ для конкретных пунктов

Q1) Две таблицы

Таблица: "TestItem"

ID, ITEM 
1, "John Doe" 
2, "Peggy Sue" 
3, "Papa Sue" 

Таблица: «Разъем»

MOTHER, CHILD 
    1,2 

В таблице разъем будет использоваться для нескольких целей (см ниже), но это дистиллированная сценарий для подключения равного типа, как, например, брак. Если «Джон Доу» женат на «Пегги Сью», этой информации также должно быть достаточно, чтобы вернуть «Пегги Сью» в браке с «Джоном Доу». Я могу сделать это в двух запросах, но для эффективности (особенно в отношении моего вопроса 2), я был бы признателен за это в одном запросе, поэтому реализация не зависит от того, каким образом определяется соединение. Каков наиболее эффективный способ сделать это?

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

//Connector through "mother"-part SELECT ITEM, SUBITEM FROM TestItem 
INNER JOIN (
    SELECT MOTHER, ITEM AS SUBITEM 
    FROM Connector 
    INNER JOIN TestItem ON Connector.CHILD = TestItem.ID 
    ) AS SUB ON TestItem.ID = SUB.MOTHER 

    /* WHERE ITEM = "John Doe" return "Peggy Sue" => Correct 
    WHERE ITEM = "Peggy Sue" return nothing => Wrong 
    */ 

//Connector through "child"-part SELECT ITEM, SUBITEM FROM TestItem 
INNER JOIN (
    SELECT CHILD, ITEM AS SUBITEM 
    FROM Connector 
    INNER JOIN TestItem ON Connector.MOTHER= TestItem.ID 
    ) AS SUB ON TestItem.ID = SUB.CHILD 


    /* WHERE ITEM = "John Doe" return nothing => Wrong 
    WHERE ITEM = "Peggy Sue" return "John Doe" => Correct 
    */ 

Q2) Наличие двух подходов, возвращенных в результате одного результата, может увеличить объем данных и, следовательно, снизить производительность. Если я сосредоточусь на Пегги Сью, я предполагаю, что сортировка только соответствующих данных как можно раньше улучшит производительность. Есть ли опрятный способ сделать это с верхнего уровня, или каждый подзапрос потребует добавления WHERE?


PS: Дополнительная информация о большей перспективе. Я планирую использовать таблицу соединителей для нескольких целей, обоих упомянутых равных типов, таких как коллеги, родственники, друзья и т. Д., А также для иерархических типов соединений, таких как мать/ребенок, лидер/сотрудник, страна/город. Таким образом, решения, устраняющие соединение типа «мать/ребенок», могут не соответствовать моей большей цели. В основном я прошу обращаться с равными типами соединений, не теряя возможности использовать одну и ту же архитектуру и данные для иерархических соединений. Пегги Сью может через тот же набор данных можно определить как дочь Papa Сю через отношение

Mother, Child, Mother_type, Child_type 
3, 2, Father, Daughter 
1, 2, Married to, Married to 

(Но это, как указано на стороне то, что я здесь с просьбой.)

+0

Ответы на вопросы SQL легко получить при условии ожидаемого результата. Кроме того, смущает видеть входные данные с матерью и ребенком, но говорить о случае с браком. – Edu

+0

Привет. Извините за путаницу. Я считаю, что ожидаемый результат был ясен.Я хотел бы получить запрос для элемента и получить соединение независимо от того, было ли установлено соединение с Джоном Доу или Пегги Сью. Итак, в основном SELECT Item, connectedItem WHERE ITEM = «Peggy Sue» должен вернуть John Doe, но важно здесь сделать это независимо от того, каким образом соединение выполняется в таблице соединителей. Таким образом, Мать/Ребенок являются архитектурными определениями (основной набор данных и вспомогательный набор данных), а «брак» - это определение связи, равное обоим путям, чтобы проиллюстрировать то, что я хочу достичь. –

+0

Отец? Дочь? Это не упоминается в вашей базе данных. – Tobb

ответ

0

UNION ALL может быть что вы ищете:

select mother.id as connectedToId, 
     mother.item as connectedToItem, 
     'Mother' as role 
from TestItem ti 
    join Connector c on c.child = ti.id 
    join TestItem mother on c.mother = mother.id 
where ti.item = 'John Doe' 
union all 
select child.id as connectedToId, 
     child.item as connectedToItem, 
     'Child' as role 
from TestItem ti 
    join Connector c on c.mother = ti.id 
    join TestItem child on c.child = child.id 
where ti.item = 'John Doe' 
+0

Большое спасибо. После исправления t.id, которое должно быть ti.id, это вернуло ожидаемые результаты. Когда я поменял пункт на «Peggy Sue» в _TWO_, где я получил правильные результаты в этом направлении. Я предполагаю, что тоже отвечает на мой вопрос 2 :-) –

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