ورود

View Full Version : کمک در نوشتن یک کوئری بصورت بازگشتی



M.YasPro
یک شنبه 03 مهر 1390, 14:29 عصر
سلام
وقت بخیر
جدول من به اینصورت هست :
id
name
father

فیلد father به id همین جدول اشاره داره ،
مثلا چندتا رکورد به این صورت میشه نوشت:
75734
من میخوام یه کوئری بنویسم که مثل یه سایت مپ تو asp بتونه سلسله مراتب مثلا شهر تهران رو بدست بیاره تا بتونم مثلا به اینصورت ازش استفاده کنم .
تهران>>ایران>>آسیا

خروجی باید بصورت یه جدول تک فیلدی باشه که به ترتیب
تهران
ایران
اسیا
لیست شده باشه

ممنون از توجهتون

یوسف زالی
یک شنبه 03 مهر 1390, 20:24 عصر
سلام دوست من.
استفاده از بازگشتی در SQL چندان توصیه نمی شه.
به این علت که هم سرباره زیادی تحمیل می کنه و هم اینکه نهایتا می تونه از 32 مرتبه بازگشت پشتیبانی کنه.
به جای اون از حلقه ها به راحتی و با سرعت بالا استفاده میشه:

declare @Tbl as table (ID int)
insert into @Tbl
select StartID

while @@ROWCOUNT> 0
insert into @Tbl
select Father
from TBL
where TBL.ID in(select * from @Tbl)and Father not in(select * from @Tbl)

همین!

select*
from @Tbl


حالا در Tbl@ مقادیر ID ها رو دارید و می تونید با استفاده از Join یا هر چیزی که راحت ترید نام ها رو هم بدست بیارید.

StartID هم ID ای هست که می خواهید برای اون داده ها رو بدست بیارید.

M.YasPro
دوشنبه 04 مهر 1390, 08:02 صبح
ممنون از جوابت
اما من نتونستم این کد رو بکار بگیرم ، میشه یه مقدار بیشتر توضیح بدی؟

یوسف زالی
دوشنبه 04 مهر 1390, 08:52 صبح
چطور استفاده کردی؟
این کدی هست که خودم دارم ازش استفاده می کنم.
کجاش اشکال دارید؟

M.YasPro
دوشنبه 04 مهر 1390, 09:23 صبح
من توی mySQL نمیتونم از این کد استفاده کنم . مثلا توی mySQL متغیر @@ROWCOUNT در دسترس نیست یا Declare رو نمیشه استفاده کرد .
اگه بتونید کد رو توضیح بدید ممنون میشم ، چون جداول و فیلدهای من با فیلدهایی که اینجا گذاشتم فرق می کنه ، چطور کار کردنش برای من مهم تره

یوسف زالی
دوشنبه 04 مهر 1390, 11:18 صبح
راستش من با MS-SQL نوشتم.
کار تطبیقش رو خودتون انجام بدید.
اما توضیح:

اول شماره ردیفی رو که می خواهیم از اونجا شروع شه رو در یک جدول موقتی می ریزیم.
بعد در یک حلقه ، پدر تمام ردیفهایی که در جدول هست اما خودش در جدول نیست رو در جدول می ریزیم و این کار رو تا وقتی انجام می دیم که دیگه ردیفی برای افزودن موجود نباشه.
تحلیلش کمی سخته اما کدش کوتاهه و کاراست.

M.YasPro
دوشنبه 04 مهر 1390, 11:29 صبح
راه دیگه ای به نظرتون نمیرسه ؟ استفاده از یه جدول واسط؟ البته بدون محدودیت سلسله مراتب

AMIBCT
دوشنبه 04 مهر 1390, 12:00 عصر
پیاده‌سازی بهینه‌ی درخت در پایگاه داده‌های متداول به دلیل اینکه جدول‌ها دو بعد دارند کار سختی است

الگوریتم‌های مختلفی هم برای حل این مشکل ایجاد شده‌اند که هر کدام از جهتی مشکل دارند
یا پیاده‌سازی آن سخت و پیچیده است
یا هزینه‌ی افزودن و کاستن زیاد است
یا حجم اطلاعات نگهداری شده بالا است

با این شکلی که شما اطلاعات را ذخیره کرده‌اید هیچ راهی جز فراخوانی تکراری Query وجود ندارد که راه مناسبی نیست و بار زیادی به پایگاه داده وارد می‌کند
اگر در شناسه‌ها هم دقت کافی نشود، حلقه‌های بی‌پایان به وجود می‌آید

اگر در برنامه‌نویسی تازه‌کار هستید و نمی‌خواهید زمان زیادی صرف کنید
بهتر است بخشی از الگوریتم را در زبان برنامه‌نویسی پیاده کنید که بسته به بستر ارتباطی و توانایی سخت‌افزار ممکن است مناسب نباشد

اگر علاقمند باشید و فرصت کافی هم داشته باشید
این صفحه را مطالعه کنید:
طولانی است ولی دید شما را تغییر خواهد داد:

http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.pdf

AMIBCT
دوشنبه 04 مهر 1390, 12:29 عصر
این مطلب هم هست که خلاصه تر است و موضوع را به صورت کلی بررسی کرده:
http://www.sitepoint.com/hierarchical-data-database/
http://www.sitepoint.com/hierarchical-data-database-2/
http://www.sitepoint.com/hierarchical-data-database-3/

anouri
سه شنبه 05 مهر 1390, 00:13 صبح
سلام
در رفرنس مای اس کیو ال نوشته

Recursive stored procedures are disabled by default, but can be enabled on the server by setting the max_sp_recursion_depth server system variable to a nonzero value. See Section 5.2.3, “System Variables” (http://barnamenevis.org/ch05s02.html#server-system-variables), for more information

یعنی بصورت پیش فرض رکرسیو در پروسیجر فعال نیست ولی میشه فعالش کرد و تعداد دفعاتش رو هم تعیین کرد
با تعیین اینها و با چند خط stored procedure مشکل حل میشه اگه نتونستین بنویسین بگین من مینویسم
برام در www.passak.org میتونید پیغام بذارید