SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 13.03.2011 00:01:13

батарейка
Участник
Зарегистрирован: 29.11.2010
Сообщений: 20

Left join?

Добрый день друзья. Второй раз возвращаюсь на ваш форум, потому как он стоит того.

У меня небольшой вопрос, над которым я вожусь второй день и все не как.

Мне нужно простроить запрос на основе трех таблиц, и все не как не выходит.

Опишу данные:

Есть три таблицы. Первые две описывают некие локации (страны и города в них).

Таблица 1:

tablename: "u_location"
fields: "id", "name", "parent_location" (фиктивное поле не хранящие ничего, но данные для него лежат в таблице о которой ниже)


Таблица 2: Так как какая то локация может находится в другой локации, и даже в нескольких одновременно есть таблица 2 в которой есть перекрестные линки

tablename: "u_location_location"
fields: "id", "location", "this"

Получается что даные выглядят так:

"u_location": "id"=1, "name"=Бразилия
"u_location": "id"=2, "name"=локация в Бразилии

То что локация "u_location": "id"=2 находится в локации "u_location": "id"=1 отмечено в таблице "u_location_location":

"u_location_location": "id"=1, "location"=1, "this"=2

Тем самым подгружая например данные "u_location": "id"=1 движек сам видя что тип данных для поля "parent_location" (называется у меня) m_select - лезет в прицепную таблицу и выискивает все что в нее вложено, в это поле, какие локации и так далее.

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

tablename: "u_programs"
fields: "id", "location", "description"

Данные выглядят так:
"u_programs": "id"=1, "location"=2, "description"=БлаБла
"u_programs": "id"=2, "location"=1, "description"=БлаБла2



Получается что нужно сделать.

Мне нужно построить таблицу в которой будут все предложения по странам. Первым делом мы конечно же сделаем так.

SELECT * FROM "u_location" WHERE "u_location"."id" = "u_programs"."location"


Данном случае результат будет, и он будет равен программы которая подвязана под "локация в Бразилии" под айди=2. Как бы все хорошо. Ну тут проблема в том что мне нужно вывести только корневые локации. Потому как бесмысленно в списке с старнами увидеть "локация в Бразилии" и только и нужно догадываться какая это страна.

И это не проблема, пишем новый запрос:

SELECT * FROM `u_location` , `u_location_location` , `u_programs` WHERE `u_programs`.`location` = `u_location_location`.`this` AND `u_location_location`.`country` = `u_location`.`id`


Такой запрос тоже работает, и находит в ответе "Бразилия" как страна источник для программы, вне записимости от того что программа находится в локации которая вложена в Бразилию.

Казалось бы вопрос решен. Но нет друзья. Если программа прицеплина не к локации которая является ребенком для родителя, а непосредственно к родителю то ничего не находится. Вот и пробую написать один запрос который бы искал и так и так. И выдавал бы список стран корневых вне зависимости где именно размещены программы - непосредственно в них или глубже в детях.

Незнаю друзья, пытался написать максимально просто. Прошу помощи.

Спасибо.

Отредактированно батарейка (14.03.2011 01:40:10)

Неактивен

 

#2 14.03.2011 23:24:15

батарейка
Участник
Зарегистрирован: 29.11.2010
Сообщений: 20

Re: Left join?

Уууу, помогите.

Неактивен

 

#3 16.03.2011 21:34:12

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Left join?

Если вложенность у Вас всегда не более одного уровня (например, или
Россия, или Москва), то можно использовать конструкцию
IF (parent = 0, this, parent) — она будет выбирать или родителя (если он
есть), или непосредственно этот элемент.

Как правило, однако, уровней вложенности несколько. Тогда простого
способа нет. Есть стандартные пути решения:
1. Написать рекурсивную процедуру (или функцию), которая найдет для
расположения корневое расположение.
2. Использовать денормализационную табличку «корневые родители».
В нее вписывать всегда родителя (если элемент без родителя, то вписывать
самого себя) — тогда, объединившись с этой табличкой, Вы получите
необходимый результат.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson