PDA

View Full Version : سوال: گزارش از یک جدول تو در تو



faryad_mfa
دوشنبه 15 شهریور 1389, 09:26 صبح
سلام خدمت دوستان
من یک جدول از قطعات دارم که هر ردیف دارای زیر مجموعه ای از قطعات هست که این قطعات به دو ستون ID و Component_ID با هم در ارتباط هستند.
حالا وقتی میخوام لیست قطعات زیر مجموعه یک قطعه رو بگیریم اونهایی رو SELECT میکنم که ستون Component_ID اونها برابر با ID قطعه مورد نظر من باشه.
حالا سوال این هست که چطور لیست تمام قطعات زیر مجموعه یک قطعه رو پیدا کنم.به این صورت که وقتی زیر مجموعه یک قطعه رو میخوام پیدا کنم لیست قطعات زیر زیر مجموعه این قطعه رو هم نمایش بده.
نکته اینجاست که میزان تو در تو بودن مجموعه ها مشخص نیست

بهزادصادقی
دوشنبه 15 شهریور 1389, 21:23 عصر
می شود از شما خواهش کنم به من کمک کنید نیاز شما را بهتر درک کنم.

فرض کنید جدول ذیل نمونه حدول قطعات شماست:



if object_id( 'dbo.parts' ) is not null
drop table dbo.parts;
go

create table dbo.parts
(
id int identity(1,1) primary key,
component_id int,
name nvarchar(100)
);

insert dbo.parts (component_id, name) values ( null, N'Product 1' );
insert dbo.parts (component_id, name) values ( 1, N'Product 1 - Subsystem 1' );
insert dbo.parts (component_id, name) values ( 2, N'Product 1 - Subsystem 1 - Component 1' );
insert dbo.parts (component_id, name) values ( 2, N'Product 1 - Subsystem 1 - Component 2' );
insert dbo.parts (component_id, name) values ( 2, N'Product 1 - Subsystem 1 - Component 3' );
insert dbo.parts (component_id, name) values ( 1, N'Product 1 - Subsystem 2' );
insert dbo.parts (component_id, name) values ( 1, N'Product 1 - Subsystem 3' );
insert dbo.parts (component_id, name) values ( 1, N'Product 1 - Subsystem 4' );
insert dbo.parts (component_id, name) values ( 8, N'Product 1 - Subsystem 4 - Component 1' );
insert dbo.parts (component_id, name) values ( 8, N'Product 1 - Subsystem 4 - Component 2' );
insert dbo.parts (component_id, name) values ( null, N'Product 2' );
insert dbo.parts (component_id, name) values ( 11, N'Product 2 - Component 1' );
insert dbo.parts (component_id, name) values ( 11, N'Product 2 - Component 2' );
insert dbo.parts (component_id, name) values ( 11, N'Product 2 - Component 3' );
insert dbo.parts (component_id, name) values ( 14, N'Product 2 - Component 3 - SubComponent 1' );
insert dbo.parts (component_id, name) values ( 14, N'Product 2 - Component 3 - SubComponent 2' );

select * from dbo.parts;


حال، فرض کنید ما یک تابع برای شما تولید می کنیم به اسم ()dbo.PartsList که ورودی آن شناسه یک قطعه می باشد، و خروجی آن لیست تمام سطرهایی در جدول بالا که زیر قطعه های آن می باشند. من لازم دارم بدانم خروجی چنین تابعی چیست، تا بتوانم آن تابع را برای شما بنویسم. پس، می شود به من بگوید با توجه به محتویات جدول بالا، خروچی سه فراخوانی زیر باید دقیقا چه باشد:



select * from dbo.PartsList( 1 );
select * from dbo.PartsList( 8 );
select * from dbo.PartsList( 14 )

faryad_mfa
چهارشنبه 17 شهریور 1389, 15:12 عصر
از لطف شما ممنونم
من این مشکل رو با حل معادله به صورت معکوس حل کردم
ببینید در جدول Component من ردیفها شامل قطعاتی هستند که به صورت زیر مجموعه از یک قطعه دیگر که در همین جدول آمده است به هم مرتبط میشوند.ستون ID و Component_ID ستون هایی هستند که این ارتباط را ایجاد میکنند. یعنی ستونی که Component_ID آن بر فرض 1 است زیر مجموعه قطعه 1 می باشد.
حالا من در یک جدول دیگر استفاده قطعات را در کارگاه ثبت میکنم.
مشکل اینجا بود که وقتی نیاز بود برفرض کدام قطعات موتور تعویض شدند من میخواستم تمامی قطعاتی که زیر مجموعه اون قطعه خاص حتی در شاخه های پایین تر بود نیز نمایش داده شود.
با حل مسئله به صورت معکوس مشکل حل شد.
به این صورت که هرقطعه تعوض شده را به صورت سلسله مراتب تا سر شاخه اصلی طی کرده و اگر جزء زیرشاخه ای که من انتخاب کرده بودم بود خروجی تابع را 1و در غیر این صورت -1 میداد
پروسیچر های بکار رفته اینها هستند

[L
DROP FUNCTION [dbo].[GetParentID]

GO



CREATE FUNCTION GetParentID
(
@Id int = 0
)
RETURNS int
AS
begin
declare @Component_Id int;
set @Component_Id=-1;

SELECT @Component_Id=Component_Id from Component where id=@Id

if @Component_Id is null
set @Component_Id=-1;

return @Component_Id
end



DROP FUNCTION [dbo].[isChild]

GO


CREATE FUNCTION isChild
(
@Component_ID int,
@Parent_ID int
)
RETURNS int
AS
begin
declare @Result int;
set @Result=-1;

declare @temp_ComponenID int;
set @temp_ComponenID=0;

declare @temp_ParentID int;
set @temp_ParentID=dbo.GetParentID(@Component_Id);

while @temp_ParentID !=-1
begin
if @temp_ParentID=@Parent_ID
--begin
set @Result=1;
--break
--end
else
begin
set @temp_ComponenID=@temp_ParentID;
set @temp_ParentID=dbo.GetParentID(@temp_ComponenID);
CONTINUE
end

if @Result=1
break
end

RETURN @Result
end




بازم از لطف شما ممنونم