2014-10-31 5 views
1

Мое приложение очень медленно, когда я перехожу к этой логике на свой язык сценариев. Я надеюсь, что есть способ использовать MySQL для этого.Дерево SELECT в MySQL

Рассмотрим следующую таблицу

ID' col1 ' ' col2' 
----------------- 
1 ' 1 ' ' 2 ' 
----------------- 
2 ' 2 ' ' 3 ' 
----------------- 
3 ' 3 ' ' 4 ' 
----------------- 
4 ' 5 ' ' 4 ' 
----------------- 

Есть ли способ, чтобы выбрать все записи, где col1 является 1, или col1 является col2 из строки из предыдущего матча?

Например, если я говорю, что нужны все записи, относящиеся к 1, я ищу, чтобы получить строки 1, 2 и 3.

Вот пример запроса, но это идет только на первый уровень глубины.

SELECT col2 FROM table WHERE (col1 = 1) OR (col1 IN (SELECT col2 FROM table WHERE (col1 = 1))) 
+0

Вы пробовали еще раз? – Raptor

+0

Вы пытались использовать 'JOIN' и' WHERE IN'? –

+0

Я использовал их как отдельно, так и не вместе. Не могли бы вы привести мне пример? – A23

ответ

1

Вам нужно будет создать хранимую процедуру, которая будет проходить через ваше дерево, пока не будет найдено больше детей. См. Recursive mysql select?, как это сделать!

В других СУБД вы можете использовать WITH RECURSIVE, который не поддерживается MySQL. Подробнее о MySQL-эмуляции этого здесь:
http://guilhembichot.blogspot.de/2013/11/with-recursive-and-mysql.html
В основном это то же самое, что и раньше, но с небольшим количеством объяснений позади него.

Там могут быть и другие способы, чтобы хранить свои данные в первую очередь, чтобы избежать таких LOOPING запросов:
What is the most efficient/elegant way to parse a flat table into a tree?

+0

Я надеялся избежать этого, но если нет другого выбора, мне придется это сделать. – A23

+0

Это зависит от того, ограничена ли ваша глубина или нет. Если это так, вы можете просто создать один запрос с несколькими объединениями. Еще несколько disuccion по теме: http://dba.stackexchange.com/questions/46127/recursive-self-joins – wolfgangwalther

+0

К сожалению, глубина не ограничена. – A23

0

@ a23 Решения, указанные выше, указывают на гораздо более надежной обработки случае.

Вот запрос, который поможет в этом случае.

SELECT * FROM test WHERE col1=1 
UNION ALL 
SELECT a.* FROM test a, test b WHERE a.col2=b.col1 AND a.col1!=1; 

Надеюсь, это поможет.

+0

Этот запрос дал мне больше, чем любой другой. Благодаря! – A23

+0

Этот запрос дает вам все виды деревьев внутри таблицы, а не только тот, который начинается с 'col1 = 1'. Последний элемент дерева также не отображается, это можно устранить, изменив предложение where на 'WHERE a.col1 = b.col2'. Я все еще хотел бы знать, как это сделать дальше? Как вы хотите уменьшить вывод только на одно дерево? – wolfgangwalther

+0

@wolfgangwalther Вы даже уверены, что выполнили этот запрос, прежде чем публиковать его, потому что он хорошо работает на моем mysql? –