PDA

View Full Version : طریقه نوشتن select به صورت بازگشتی



iekrang
سه شنبه 05 مهر 1390, 15:59 عصر
با سلام
فرض کنید که جدول شامل سه فیلد ID,Name,ParentIDهست.و اطلاعات داخل اون به صورت بازگشتی ممکنه که هر سطر بوسیله فیلد پرنت،فرزند سطر دیگه باشه
سطرهایی که خودشون به اصطلاح پدر هستند و زیر شاخه دیگری نیستند،فیلد parent اونها خالی هست.

چطور میتونم یه select به صورت زیر بنویسم:
پدر>فرزند1>فرزند2>...

ممنون میشم اگه راهنماییم کنید

یوسف زالی
سه شنبه 05 مهر 1390, 20:31 عصر
سلام. اگر تعداد مراحل از قبل معین باشه میشه به ازای هر فرزند یک SubSelect به صورت جدول با جدول اصلی join زد.
select * from TBL join (select * from Tbl where ... ) X on ...
اگر تعداد رو میشه مشخص کرد اما در لحظه اجرا معین میشه ، به صورت داینامیک میشه نوشت.
اگر تعداد مشخص نیست میشه به صورت یک حلقه خروجی مورد نظر رو تولید کرد.

کدام یک مد نظر شماست؟

iekrang
پنج شنبه 07 مهر 1390, 15:31 عصر
مرسی از پاسختون
مشکلم همینه که تعداد مشخص نیست

sanay_esh
پنج شنبه 07 مهر 1390, 15:46 عصر
جهت استخراج اینجور اطلاعات باید از کرسر cursor استفاده کنید

mehdi.mousavi
پنج شنبه 07 مهر 1390, 15:59 عصر
با سلام فرض کنید که جدول شامل سه فیلد ID,Name,ParentIDهست.و اطلاعات داخل اون به صورت بازگشتی ممکنه که هر سطر بوسیله فیلد پرنت،فرزند سطر دیگه باشه سطرهایی که خودشون به اصطلاح پدر هستند و زیر شاخه دیگری نیستند،فیلد parent اونها خالی هست. چطور میتونم یه select به صورت زیر بنویسم: پدر>فرزند1>فرزند2>... ممنون میشم اگه راهنماییم کنید

سلام.
می تونید با استفاده از CTE ها، بدین شکل عمل کنید:

;WITH cte AS (
SELECT
CAST('>' + t.Label AS NVARCHAR(MAX)) AS [Path],
t.ParentId,
t.[Id]
FROM MyTable t
WHERE t.ParentId IS NULL

UNION ALL

SELECT
CAST(cte.[Path] + '>' + t.Label AS NVARCHAR(MAX)),
t.ParentId,
t.Id
FROM MyTable t
INNER JOIN cte ON cte.Id = t.ParentId
)
SELECT * FROM cte

موفق باشید.

پاورقی: در SELECT اول، کلیه نودهای Root رو انتخاب می کنم (همونهایی که ParentId اشون NULL هست). سپس در Select دوم، نتایج رو بر اساس ParentId و Id ترکیب میکنم و Path مورد نظر رو میسازم.

یوسف زالی
پنج شنبه 07 مهر 1390, 16:06 عصر
همیشه می شه از کرسر دوری کرد.
برای مثال میشه از یک تابع مثل زیر استفاده کرد:

declare @st varchar(max)
set @st = ''
declare @LastSN int
set @LastSN = YourSerialOfFirstNode
declare @NewSN int
declare @Data varchar(100)
while 1 = 1
begin
select @Data = ltrim(rtrim(YourDataForShowing)), @NewSN = isnull(FatherSN, 0)
from YourTable
where NodeSN = @LastSN

set @st = @st + case @st when '' then '' else ' -> ' end + @Data

if @NewSN = 0
break

set @LastSN = @NewSN
end
print @st