一時テーブルをループせずにjoinを使用するだけで親子クエリを実行できますか?自己結合クエリ
データベースサンプル:
menuid name parent url
----------------------------------------------------------
A0000 Master A0000 #
A0001 Rekening A0000 /master/rekening.aspx
A0002 Master Nominal A0001 /master/nominal.aspx
A0003 Master Satuan Other A0001 /master/satuan.aspx
A0004 Master Kondisi A0000 /master/kondisi.aspx
A0005 Master Tujuan A0003 /master/tujuan.aspx
A0006 Master Item A0003 /master/item.aspx
A0007 Master Warehouse A0000 /master/warehouse.aspx
A0008 Master Kapal A0006 /master/kapal.aspx
望ましい結果がuri = '/master/kapal.aspx'
選びました場合:
menuid name parent url
----------------------------------------------------------
A0000 Master A0000 #
A0001 Rekening A0000 /master/rekening.aspx
A0003 Master Satuan Other A0001 /master/satuan.aspx
A0006 Master Item A0003 /master/item.aspx
A0008 Master Kapal A0006 /master/kapal.aspx
望ましい結果をuri = /master/tujuan.aspx'
を選びました場合:
menuid name parent url
----------------------------------------------------------
A0000 Master A0000 #
A0001 Rekening A0000 /master/rekening.aspx
A0005 Master Tujuan A0003 /master/tujuan.aspx
サンプルクエリ:
hieararchyとdeclare @menuid varchar(255) = 'menuid'
declare @parent varchar(255) = 'parent'
declare @temp_parent varchar(255)
declare @i smallint = 0
delete from temp_menu
while (@menuid <> @parent)
begin
if(@i = 0)
begin
insert into temp_menu
select * from menu where uri = '/master/kapal.aspx'
select @menuid = menuid, @parent = parent from menu where uri = '/master/kapal.aspx'
set @i = 1;
end
else
begin
insert into temp_menu
select * from menu where menuid = @parent
select @menuid = menuid, @temp_parent = parent from menu where menuid = @parent
set @parent = @temp_parent;
end
end
select * from temp_menu
サンプル:UPDATED
A0000
|_______________________
| | |
A0001 A0004 A0007
|________
| |
A0002 A0003
|_______
| |
A0005 A0006
|
A0008
: 私はmenuid
と同じparent
は、あるいは全くmenuid
が存在しない場合menuid
からparent
とが停止したノードから可能な最長のブランチからのすべての行を取得したいですparent
と一致します。
が追加されたスクリプトと上記所望のサンプルのためのサンプル
IF OBJECT_ID('dbo.menu', 'U') IS NOT NULL
DROP TABLE dbo.menu
GO
IF OBJECT_ID('dbo.temp_menu', 'U') IS NOT NULL
DROP TABLE dbo.temp_menu
GO
IF OBJECTPROPERTY(object_id('dbo.sp_get_parent'), N'IsProcedure') = 1
DROP PROCEDURE dbo.sp_get_parent
GO
create table dbo.menu (
menuid varchar(255)
, name varchar(255)
, parent varchar(255)
, uri varchar(255)
);
insert into dbo.menu (menuid, name, parent, uri)
values ('A0000', 'Master', 'A0000', '#')
, ('A0001', 'Rekening', 'A0000', '/master/rekening.aspx')
, ('A0002', 'Master Nominal', 'A0001', '/master/nominal.aspx')
, ('A0003', 'Master Satuan Other', 'A0001', '/master/satuan.aspx')
, ('A0004', 'Master Kondisi', 'A0000', '/master/kondisi.aspx')
, ('A0005', 'Master Tujuan', 'A0003', '/master/tujuan.aspx')
, ('A0006', 'Master Item', 'A0003', '/master/item.aspx')
, ('A0007', 'Master Warehouse', 'A0000', '/master/warehouse.aspx')
, ('A0008', 'Master Kapal', 'A0006', '/master/kapal.aspx');
create table dbo.temp_menu (
menuid varchar(255)
, name varchar(255)
, parent varchar(255)
, uri varchar(255)
);
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[sp_get_parent]
@uri VARCHAR (255)
AS
declare @menuid varchar(255) = 'menuid'
declare @parent varchar(255) = 'parent'
declare @temp_parent varchar(255)
declare @i smallint = 0
delete from temp_menu
while (@menuid <> @parent)
begin
if(@i = 0)
begin
insert into temp_menu
select * from menu where uri = @uri
select @menuid = menuid, @parent = parent from menu where uri = @uri
set @i = 1;
end
else
begin
insert into temp_menu
select * from menu where menuid = @parent
select @menuid = menuid, @temp_parent = parent from menu where menuid = @parent
set @parent = @temp_parent;
end
end
select * from temp_menu order by menuid asc
GO
は、このクエリを試すことができますで
sp_get_parent '/master/kapal.aspx'
と
sp_get_parent '/master/tujuan.aspx'
https://stackoverflow.com/questions/tagged/ sql-server + recursive-query –
したがって、最長のブランチに属するノードを取得したいですか? –
@GiorgosBetsos:理解を深めるために階層スキームを更新します。ありがとうございました。 –