Как правильно использовать правильное соединение - PullRequest
1 голос
/ 05 сентября 2011

Расположение таблиц

loc_id  loc_name        hier2   hier3   hier4   hier5   hier6   hier7   hier8   hier9   
152675  Castelli        105     109     0       319     14356   152673  152675  0   
14356   Rome            105     109     0       319     14356   0       0       0       
...

Ссылки на таблицы Таблицы

oid     name        loc_id
12      Demo Villa  152675
...

Теперь я пытаюсь найти некоторые записи, которые ищет пользователь, введя строку "caste":

SELECT geo.loc_id, geo.loc_name AS name
FROM locations AS geo  
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id  
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id  
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id    
WHERE geo.loc_name LIKE 'caste%'
GROUP BY geo.loc_name

Это работает.Я получаю запись с помощью loc_id 152675

Теперь я хочу получить только те записи, в которых есть объекты. Поэтому я присоединяюсь к справочной таблице:

SELECT geo.loc_id, geo.loc_name AS name
FROM locations AS geo  
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id  
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id  
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id  
RIGHT JOIN locations_xref AS gx ON geo.loc_id = gx.loc_id 
WHERE geo.loc_name LIKE 'caste%'
GROUP BY geo.loc_name

Это работает.Снова я получаю запись местоположения с помощью loc_id 152675, потому что есть ссылка.

ПРОБЛЕМА

Теперь пользователь ищет «Рим».Я не получаю никаких записей, потому что нет прямой ссылки на объект "Рим".Существующий объект привязан к району Рима.

Как видно, записи района и города имеют идентификаторы иерархии, которые можно использовать для определения правильной структуры.Я просто не могу заставить его работать вместе со справочной таблицей, поэтому я получаю только те объекты, которые находятся в "Риме" или в районе, который является частью Рима.

Любая помощь с благодарностью!

Ответы [ 2 ]

1 голос
/ 05 сентября 2011

Вы можете настроить свой запрос (как предложил Каролис), но я не думаю, что это даст вам то, что вы хотите. Ваш запрос вернет 'Castelli' при поиске 'Rome%', но не вернет 'Rome'. «Рим» не вернется, потому что «Рим» в вашей таблице внешних ссылок отсутствует.

Чтобы вернуть 'Рим' с таким запросом, вам нужно вставить строку для 'Рима' в таблицу внешних ссылок.

Вы можете получить все, что находится "в" Риме, с помощью UNION, но он вообще не ссылается на вашу таблицу внешних ссылок.

select la.loc_id, la.loc_name
from locations la
where la.loc_name like 'Rome%'
union 
select lb.loc_id, lb.loc_name
from locations lb
inner join locations lc on lc.hier6 = lb.hier6

Мне не ясно, как вы определяете, какой столбец использовать для объединения во время выполнения.

Позже. , .

Если вы не знаете, какие столбцы использовать во время выполнения, вы должны СЛЕДУЕТ ПОДКЛЮЧИТЬСЯ ко всем из них. А поскольку вы не знаете, может ли строка поиска ссылаться на значение, соединенное через столбец hier2, hier3, hier4 и т. Д., То вам также необходимо проверить соответствие каждого из этих столбцов.

Если location_xref действует как фильтр, то вам нужно внутреннее соединение для этой таблицы вместе со строкой для «Рима». (Потому что у вас есть недвижимость в Риме.) Возможно, что-то в этом роде.

SELECT geo.loc_id, geo.loc_name AS name
FROM locations AS geo  
LEFT JOIN locations AS geoh2 ON geo.hier2 = geoh2.loc_id  
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id  
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id  
LEFT JOIN locations AS geoh5 ON geo.hier5 = geoh5.loc_id  
LEFT JOIN locations AS geoh6 ON geo.hier6 = geoh6.loc_id  
LEFT JOIN locations AS geoh7 ON geo.hier7 = geoh7.loc_id  
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id  
LEFT JOIN locations AS geoh9 ON geo.hier9 = geoh9.loc_id  
INNER JOIN locations_xref lx on lx.loc_id = geo.loc_id
WHERE   geo.loc_name LIKE 'Rom%' 
   or geoh2.loc_name like 'Rom%'
   or geoh3.loc_name like 'Rom%'
   or geoh4.loc_name like 'Rom%'
   or geoh5.loc_name like 'Rom%'
   or geoh6.loc_name like 'Rom%'
   or geoh7.loc_name like 'Rom%'
   or geoh8.loc_name like 'Rom%'
   or geoh9.loc_name like 'Rom%'

Прежде чем вы слишком увлечетесь этой моделью, вам следует взглянуть на антипаттерны базы данных Билла Карвина . «Наивные деревья» начинаются на слайде 48.

1 голос
/ 05 сентября 2011

Я не знаю много о ваших данных, но на первый взгляд кажется, что hier6 содержит информацию о взаимоотношениях между Римом и Кастелли Таким образом, запрос, который вам нужен, может выглядеть примерно так:

SELECT geo.loc_id, geo.loc_name AS name
FROM locations AS geo  
LEFT JOIN locations AS geoh3 ON geo.hier3 = geoh3.loc_id  
LEFT JOIN locations AS geoh6 ON geo.hier6 = geoh6.loc_id  
LEFT JOIN locations AS geoh4 ON geo.hier4 = geoh4.loc_id  
LEFT JOIN locations AS geoh8 ON geo.hier8 = geoh8.loc_id  
RIGHT JOIN locations_xref AS gx ON geo.loc_id = gx.loc_id 
WHERE geoh6.loc_name LIKE 'rome%'
GROUP BY geo.loc_name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...