join, exists - возник тупой вопрос

Farsh

~ on ~ high ~ wave ~
join, exists - возник тупой вопрос

Добрый вечер.
Извините, что я немного туплю ;)

Схемы таблиц выкладывать не буду, смысла нет, все и так понятно.

И так, у нас имеются 3 таблицы ( many to many ) :
tag, document, tag_to_document

Запрос вида :
SELECT d.id as document_id, t.name as tag_name
FROM document d
LEFT JOIN tag_to_document td ON d.id = td.document_id
LEFT JOIN tag t ON t.id = td.tag_id
Выбирает все документы со всеми ассоциируемыми тагами.

Задача: выбрать все документы со всеми ассоциируемыми тагами, но чтоб в этих тагах был 'tag_name'
(или представим реальную ситуацию - юзер кликает на таг, а ему вываливаются все документы, ассоциированные с этим тагом + все таги к этим документам).

Сходу подумал типо такого, предполагая, что сначала мы отрежем все документы, к которым нужный таг не относится ( inner join ), а потом сделаем уже полноценный join, получив все таги, но этот вариант неверный:
SELECT d.id as document_id, t.name as tag_name
FROM document d
LEFT JOIN tag_to_document td ON d.id = td.document_id
INNER JOIN tag t_check ON t_check.id = td.tag_id AND td.tag_name = 'tag_name'
LEFT JOIN tag t ON t.id = td.tag_id
Как же все-таки сделать это 'in true way' ?
p.s. юзаю Doctrine
 

zerkms

TDD infected
Команда форума
у тебя сейчас почти наверняка будет фулскан таблицы document (хотя ещё неизвестно как в конкретно твоём случае развернёт запрос оптимизатор)

Почему бы не начать с:

SELECT * FROM tag WHERE tag_name = 'tag_name'

Выбрали нужный тег. Теперь к нему первой парой джоинов через таблицу связей выбираем все сущности с этим тегом.

А затем опять же парой джоинов выбираем все теги сущности. Но я бы лучше провёл денормализацию и хранил все теги сущности рядом с самой сущностью, в сериализованном виде.
 

Farsh

~ on ~ high ~ wave ~
Автор оригинала: zerkms
SELECT * FROM tag WHERE tag_name = 'tag_name'
Выбрали нужный тег. Теперь к нему первой парой джоинов через таблицу связей выбираем все сущности с этим тегом.
А затем опять же парой джоинов выбираем все теги сущности.
спасибо, думал об этом, просто уж хотелось сделать это красиво ;)

Но я бы лучше провёл денормализацию и хранил все теги сущности рядом с самой сущностью, в сериализованном виде.
Смысл понял. Когда думал над схемой БД, немного загонялся над тем, как лучше представить связь tag -> document, но сделал many to many ( так показалось проще и "красивей" ). А над оптимизацией запросов пока мне вообще загоняться не нужно, так как a) сайт будет интранет для небольшой компании, б) времени нет, в) да и тестирую на mysql, а деплоить придется на mssql .. ;)
 

Wicked

Новичок
SELECT d.id as document_id, t.name as tag_name
FROM document d
LEFT JOIN tag_to_document td ON d.id = td.document_id
INNER JOIN tag t_check ON t_check.id = td.tag_id AND td.tag_name = 'tag_name'
LEFT JOIN tag t ON t.id = td.tag_id
таблица tag_to_document тоже должна участвовать 2 раза:
t_check -> td1 -> d -> td2 -> t

но еще лучше сделать так:
выбирать только те документы, которые связаны с выбранным тегом (t_check -> td1 -> d), а для них теги уже подгружать через loadrelated
 

Farsh

~ on ~ high ~ wave ~
Автор оригинала: Wicked
таблица tag_to_document тоже должна участвовать 2 раза:
t_check -> td1 -> d -> td2 -> t

но еще лучше сделать так:
выбирать только те документы, которые связаны с выбранным тегом (t_check -> td1 -> d), а для них теги уже подгружать через loadrelated
спасибо, то что нужно.
 
Сверху