Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MySQL > Выборка из одной таблицы несколько раз одновремено


Автор: tot 25.12.2007, 09:40
Есть таблица хранящая древовидную структру. В ней хранятся id родителя и дочерней записи. Нужно получить дополнительную информацию и о родителе и о предке. Сейчас приходится это делать двойным обращением к таблице. В первом обращении выбирается все для родителя, во втором обращении все для потомка. Получается примерно так:

Код

SELECT
    table.name                AS child_name
    table_parent.name        AS parent_name
FROM
    tree
    LEFT JOIN table ON tree.id_child = table.id
    LEFT JOIN
    (
    SELECT
        table.id
        , table.name
    FROM
        table                        
    ) AS table_parent ON tree.id_parent = table_parent.id 


Как можно сделать тоже самое не прибегая к подчиненому запросу?

Автор: Akina 25.12.2007, 10:28
через UNION

Автор: tot 25.12.2007, 10:40
Цитата(Akina @ 25.12.2007,  10:28)
через UNION

И как это(пример если можно)? UNION объединит результат нескольких выборок в одну, а мне нужно получить имя родительского и дочернего объекта в одной строке результат.

Автор: skyboy 25.12.2007, 11:00
не совсем понял, что тебе надо.
возможно, тебе надо присоединить(JOIN) одну и ту же таблицу дважды с разными параметрами связки. тогда тебе помогут алиасы(псевдонимы).
Код

SELECT `table_child`.`name` AS `child_name`,`table_parent`.`name` AS `parent_name`
FROM `tree`
LEFT JOIN `table` `table_child` 
ON `tree`.`id_child` = `table_child`.`id`
LEFT JOIN `table` `table_parent` 
ON `tree`.`id_parent` = `table_parent`.`id` 

по крайней мере, получается то же, что и твой запрос, но без подзапроса.
если тебе нужно другое, то, будь добр, объясни внятнее.

Автор: tot 25.12.2007, 11:27
Цитата(skyboy @ 25.12.2007,  11:00)
по крайней мере, получается то же, что и твой запрос, но без подзапроса.
если тебе нужно другое, то, будь добр, объясни внятнее.

Да, это именно тоже самое(это я и хочу). Но разве в этом запросе не происходит двойного обращения к таблице table(два раза делаем JOIN)? 

Автор: Akina 25.12.2007, 11:38
Цитата(tot @  25.12.2007,  11:40 Найти цитируемый пост)
а мне нужно получить имя родительского и дочернего объекта в одной строке результат. 

А у меня всегда были проблемы с телепатией.
Кстати, как ты намереваешься выводить все в ОДНОЙ строке? для тех, у кого НЕСКОЛЬКО потомков? а если еще и несколько родителей...

Автор: tot 25.12.2007, 12:54
Цитата(Akina @ 25.12.2007,  11:38)
Цитата(tot @  25.12.2007,  11:40 Найти цитируемый пост)
а мне нужно получить имя родительского и дочернего объекта в одной строке результат. 

А у меня всегда были проблемы с телепатией.
Кстати, как ты намереваешься выводить все в ОДНОЙ строке? для тех, у кого НЕСКОЛЬКО потомков? а если еще и несколько родителей...

Одна строка результата будет содержать имя родителя и имя потомка. Если у одного родителя N потомков, то N строк результата и будет.

Автор: Akina 25.12.2007, 13:01
А смысл? по моему, вывод по типу
Код

ID Parent Child
 1           2
 1           3
 1           4
 1     7     
 2           9
 2     1    
вполне сносная замена тому, что ты хочешь

Автор: tot 25.12.2007, 13:26
Цитата(Akina @ 25.12.2007,  13:01)
А смысл? по моему, вывод по типу
Код

ID Parent Child
 1           2
 1           3
 1           4
 1     7     
 2           9
 2     1    
вполне сносная замена тому, что ты хочешь

Если честно я не понял что ты написал. 
У меня конкретный вопрос. Я в своем первом сообщении привел код, вот и хочу узнать можно получить тот же самый результат не используя подчиненый запрос, т.е. не включая одну и туже таблицу два раза(т.е. как оптимальнее написать этот запрос).

Автор: Akina 25.12.2007, 13:37
Цитата(tot @  25.12.2007,  14:26 Найти цитируемый пост)
можно получить тот же самый результат не используя подчиненый запрос,

можно, skyboy дал код.

Цитата(tot @  25.12.2007,  14:26 Найти цитируемый пост)
не включая одну и туже таблицу два раза

а вот это - нет.

Автор: skyboy 25.12.2007, 13:39
Цитата(tot @  25.12.2007,  12:26 Найти цитируемый пост)
 тот же самый результат не используя подчиненый запрос

я же привел код. чем не устраивает?
Цитата(tot @  25.12.2007,  12:26 Найти цитируемый пост)
т.е. не включая одну и туже таблицу два раза

связь по разным полям для двух разных случаев. все равно, явно или неявно, будет дважды обработка таблицы.
Цитата(tot @  25.12.2007,  12:26 Найти цитируемый пост)
т.е. как оптимальнее написать этот запрос

оптимальность - она не в количестве обращений к таблицам. и не в наличии/отсутствии подзапросов.  оптимальность - во времени выполнения или в занимаемой при выполнении памяти. сделай замеры и сравни.

Автор: tot 25.12.2007, 14:13
Цитата(skyboy @ 25.12.2007,  13:39)
я же привел код. чем не устраивает?

Всем устраивает. Спасибо. А замеры действительно надо будет сделать.

Автор: vi_k 29.12.2007, 10:17
А действительно ли нужно использовать отдельную таблицу `tree`? Если у потомка только один родитель - достаточно добавить в `table` поле `parent_id`, imho, конечно.

Добавлено через 14 минут и 16 секунд
И соответственно запрос упрощается:

Код

SELECT *
FROM `table` `childs`
LEFT JOIN `table` `parents`
ON `childs`.`parent_id` = `parents`.`item_id`;

Автор: vi_k 29.12.2007, 10:35
Тогда и всех родителей родителей легко можно вытащить  smile 

Код

SELECT *
FROM `table` childs
LEFT JOIN `table` parents
ON childs.parent_id = parents.item_id
LEFT JOIN `table` parents2
ON parents.parent_id = parents2.item_id
LEFT JOIN `table` parents3
ON parents2.parent_id = parents3.item_id
LEFT JOIN `table` parents4
ON parents3.parent_id = parents4.item_id;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)