LINUX.ORG.RU

Mysql цепочка

 , ,


0

1

Здравствуйте. Есть таблица

id, to_cid, to_uid, from_cid, from_uid
1, 5750, 1, 4146, 2
2, 4146, 2, 5748, 3
3, 5745, 5, 5749, 1
4, 4140, 3, 4141, 4

Как по to_uid и from_uid (например 1), чтоб получилась такая цепочка вложенностью до 5ти (включительно)

chains
(5750, 4146, 5748) - в этом примере тут вложенность 3
(5749, 5745) - в этом примере тут вложенность 2

Для uid 2 должно получиться

chains
(4146, 5748, 5750)
(5745, 5749)

Для uid 3 должно получиться

chains
(4140, 4141)
(5748, 4146, 5750)

Для uid 4 должно получиться

chains
(4141, 4140)

Как только не пробовала, всё время то дубли, то не все выбирается, то ещё чтото


В чем суть вопроса? Вы не можете исправить баг в вашем коде? Приведите код. Или может вам нужно помочь составить алгоритм?

goingUp ★★★★★
()
Ответ на: комментарий от jessgt

Допустим для самого первого примера
1) $cid = 5750
2) делаем в цикле
2а) select * from table where to_cid=$cid
2b) если результат пустой выходим из цикла
2c) дописываем в конец массива результата выбраные запросом значения to_cid from_cid
2d) $cid = $from_cid
3) на выходе из цикла убиваем дубли из массива с помощью array_unique

goingUp ★★★★★
()
Последнее исправление: goingUp (всего исправлений: 1)
Ответ на: комментарий от goingUp

По подобному алгоритму делала уже, только без чистки от дублей, и с выборкой to_cid = $cid or from_cid = $cid,

Но думала что вдруг как то через mysql можно ускорить и без чисток от дублей на php.

ой... сейчас заметила что не так делала, делала выборку по to_uid и from_uid, чтоб по пользователю

jessgt
() автор топика
Последнее исправление: jessgt (всего исправлений: 1)
Ответ на: комментарий от jessgt

Да, действительно можно

1) $cid = 5750
2) делаем в цикле
2а) дописываем в конец массива результата $cid
2b) select * from table where to_cid=$cid
2c) если результат пустой выходим из цикла
2e) $cid = $from_cid

goingUp ★★★★★
()
Ответ на: комментарий от jessgt

как то через mysql можно ускорить

Всмысле выбрать всю цепочку одним запросом? Можно. Но это не просто. Если уровень вложености до 5, можно сделать через join, если уровень вложенности неограничен, можно сделать через nested sets (нужно будет добавить в БД дополнительные поля). Но не стоит заморачиваться.

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Да, желательно одним запросом, чтоб передать uid и выбралось всё с уровнем вложенности до 5 (больше 5ти не будет). Сейчас домой еду, проверю ваш способ выше

jessgt
() автор топика
Ответ на: комментарий от jessgt

Через джоины как-то так, для 3 уровней

select t1.to_cid as cid1,  t1.from_cid as cid2, t2.from_cid as cid3, t3.from_cid as cid4
from table t1
join table t2 on t2.to_cid=t1.from_cid
join table t3 on t3.to_cid=t2.from_cid
where t1.to_cid=?

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Спасибо Вам, попробую, а то по предыдущему всё же дубли как и были, либо не все выделялись. А можно как нибудь чтоб указать не cid, а uid и от него цепочки сформировались? или сначала

select to_cid from chains where to_uid = ? or from_uid = ?

jessgt
() автор топика
Последнее исправление: jessgt (всего исправлений: 1)
Ответ на: комментарий от goingUp

Спасибо вам, код выше не совсем работал по началу, но как пример хорошо помог мне, добавила чтоб последний id не терялся

t4.to_cid as cid5
а так же вместо join написала left join. так же т.к. перед этим делаю выборку
where (from_uid = :id) or (to_uid = :id)
приходится в цикле выполнять этот запрос с join'ами, и проверять id пользователя == from_uid или to_uid, если from_uid, то тогда немного по другому выполнять запрос в select везде поменять from => to, а to => from и в where тоже.

это я написала на случай если у кого-нибудь будет такой же вопрос. было бы отлично если одним запросом можно было бы всё это сделать, передав uid пользователя, но и так очень даже хорошо :) спасибо ещё раз

jessgt
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.