Выборка из таблицы объектов по таблице связей

Bible_Black

Новичок
Выборка из таблицы объектов по таблице связей

Имеются две таблицы:

1) Таблица объектов
Objects
-----------------------------
id
type

2) Таблица связей между объектами
Relations
-----------------------------
parentId
childId
relationType

Требуется выбрать из талицы Objects все объекты типа A (Objects.type='A') не связанные в таблице Relations ни с одним объектом типа B (Objects.type='B') по связи relationA (Relations.relationType='relationA')

Например для двух таблиц:

id type
1 A
2 B
3 D

и

parentId childId relationType
1 2 relationA
1 3 relationB
3 1 relationA
3 2 relationB

необходимо получить объект с id=3, не связанный ни с одним объектом типа B по связи relationA

Пока есть только вариант со временной таблицей, но возможно-ли получить требуемый результат как-то иначе, например при помощи LEFT JOIN?
 
м?
[sql]
SELECT * FROM `Objects` `o`
LEFT JOIN `Relations` `r` ON `r`.`parentId` = `o`.`id` AND `r`.`childId` = 2 AND `r`.`relationType` = 'relA'
WHERE `relationType` IS NULL
[/sql]

не проверял
 
zerkms не совсем верно поняли вопрос. В том то и дело, что childId не известен, его вообще может не быть, известны только тип связи и тип связанных объектов и требуется извлечь объекты для которых нет данного типа связи с данным типом объектов!
 
и чем мой запрос не удовлетворяет твоим требованиям?
попробовал - он возвращает B и D
согласно твоим требованиям ни у B ни у D нет связей с объектом класса B (да, повторы легко можно убрать) с типом связи relationA
 
Это ясно, но нужно получить объекты у которых НЕТ(!) связей типа A ИМЕННО(!) с объектами типа B. Причём не исключается возможность связей типа A с другими типами объектов или связей другого типа с объектами типа B!
 
[sql]
SELECT * FROM `o`
LEFT JOIN `r` `r1` ON `r1`.`parent` = `o`.`id` AND `r1`.`child` = 2 AND `r1`.`relType` = 'relA'
WHERE `r1`.`relType` IS NULL AND `o`.`id` != 2
[/sql]

Код:
+------+------+--------+-------+---------+
| id   | name | parent | child | relType |
+------+------+--------+-------+---------+
|    3 | D    |   NULL |  NULL | NULL    |
+------+------+--------+-------+---------+
1 row in set (0.00 sec)

что я делаю не так?
 
Вот этого

`r1`.`child` = 2

в условии нет. Известен только тип дочерних объектов. Информации о типе в таблице связей нет!
 
[sql]
SELECT * FROM `o`
INNER JOIN `o` `o2` ON `o2`.`name` = 'B'
LEFT JOIN `r` `r1` ON `r1`.`parent` = `o`.`id` AND `r1`.`child` = `o2`.`id` AND `r1`.`relType` = 'relA'
WHERE `r1`.`relType` IS NULL AND `o`.`id` != `o2`.`id`
[/sql]

???

Информации о типе в таблице связей нет!
если нет, то как происходит связь тогда???????
 
Таким образом таблицу Objects придётся цеплять в любом случае 2 раза: для выборки только объектов типа A и только связанных с ними по типу С объектов типа B.

Таким образом ещё раз уточню результат должно быть

такие A, что не существует цепочки A-C-B

-~{}~ 19.03.07 11:36:

Объекты свзываются следующим образом

Идентификатор родительского - Идентификатор дочернего - Тип связи

-~{}~ 19.03.07 11:36:

То есть из таблицы связей невозможно узнать какого типа объекты связаны!
 
я уже ничего не понимаю. или я тупой или кто-то совершенно не умеет объяснять что у него есть и что ему нужно ;)
 
Решил задачу следующим запросом

SELECT A.* FROM object A
WHERE (A.objectType='type1') AND (A.objectId NOT IN (SELECT B.parentId FROM relation B, object C WHERE (B.relationType='relation1') AND (B.childId=C.objectId) AND (C.objectType='type2')))
 
То есть из таблицы связей невозможно узнать какого типа объекты связаны!
тогда зачем существует таблица связей если из неё как оказывается почти никакой полезной информации почерпнуть невозможно? или ты что-то снова умалчиваешь?
 
Таким образом выбираются все объекты типа "type1" не имеющие связей типа "relation1" с объектами типа "type2"

-~{}~ 19.03.07 11:43:

А зачем дублировать информацию о типах объектов в таблице связей??? Таблица связей нужна чтобы соединить уникальные идентификаторы двух объектов и указать каким образом!

-~{}~ 19.03.07 11:45:

zerkms спасибо за попытку помочь!

-~{}~ 19.03.07 11:48:

Можем потолковать о структуре системы, но наверно вынести это в отдельную тему!
 
ужасный запрос......
в котором к тому же содержатся данные (условия) которые в изначальном вопросе не упоминались ;)

(я про то - что ты сам запрашиваешь конкретно type1 и type2) :)

-~{}~ 19.03.07 18:50:

и всё таки, у меня уже исключительно спортивный интерес
почему запрос
[sql]
SELECT *
FROM `o`
INNER JOIN `o` `o2` ON `o2`.`name` = 'B' AND `o`.`id` != `o2`.`id`
LEFT JOIN `r` `r1` ON `r1`.`parent` = `o`.`id` AND `r1`.`child` = `o2`.`id` AND `r1`.`relType` = 'relA'
WHERE `r1`.`relType` IS NULL
[/sql]
всё таки не решает поставленной задачи?
 
Не решает, он вообще решает что-то совершенно другое :)
Хотя бы потому что в нём не указан ни разу тип объектов, ни того что является родителем, ни дочерних (а это ключевой момент задачи)!

Ещё раз объясню максимально полно задачу:

1) Имеются объекты различных типов с уникальными идентификаторами (тип и идентификатор задаются в таблице Objects)
2) Между объектами могут существовать связи различных типов. Связь задаётся тремя параметрами: идентификатор родительского объекта, идентификатор дочернего, тип связи. Для простоты пусть любой объект может быть связан с любым другим (в том числе и сам с собой, петля) по любому типу связи.
3) Задача - сделать выборку объектов типа A, для которых не существует связей типа B с объектами типа С. То есть показать отсутствие цепочки связей A-B-C!
4) Объекты ни коем образом не фильтруются, там по имени или идентификатору, нужно извлечь все объекты типа A!
5) Таким образом нам известны: тип объектов A, тип связи B, тип объектов С, ничего более!

-~{}~ 19.03.07 12:28:

Странно, но вот то что я писал в начале:

Требуется выбрать из талицы Objects все объекты типа A (Objects.type='A') не связанные в таблице Relations ни с одним объектом типа B (Objects.type='B') по связи relationA (Relations.relationType='relationA')

Это таже задача. И ещё вопрос, почему мой запрос плох, по времени или по каким критериям?

-~{}~ 19.03.07 12:29:

Мой запрос выбирает все объекты типа 'type1' для которых отсутствует связь type1-relation1-type2

-~{}~ 19.03.07 12:33:

То есть мне нужно контролировать не просто relation1 IS NULL, а более точно relation1 с объектом type2 IS NULL!
 
Сверху