有没有办法将select子句与条件从另一个select子句驱动的where子句一起应用?

时间:2019-06-20 06:10:04

标签: sql-server

ID     AGENT_CODE     MANAGER_CODE    DESIGNATION            NAME
1      0001           0               GEN MANAGER            STEVE
2      0002           0001            REGIONAL MANAGER       ALBERT
3      0003           0001            REGIONAL MANAGER       JOHN
4      0004           0002            UNIVERSAL TELLER       HENRY
5      0005           0003            UNIVERSAL TELLER       MEVRICK
6      0006           0002            TELLER                 BRINGER
7      0007           0003            TELLER                 ANTONIO

这是示例数据...

现在,我希望得到输入的ID,例如得到ID = 6

现在,在ID = 6

的情况下,我只想选择连接的父母孩子

6 0006 0002 TELLER BRINGER

由于我有Manager ID 0002,因此应该在0002的{​​{1}}中获取Agent ID的结果

ID = 2

现在我有2 0002 0001 REGIONAL MANAGER ALBERT,因此它应该获取Manager ID 0001的结果 这是Agent ID 0001

ID = 1

现在我们将1 0001 0 GEN MANAGER STEVE设为Manager ID,因此停止向上移动,然后再次回到0,我们从这里开始。

ID = 6

现在,我们将在其他6 0006 0002 TELLER BRINGER中检查此行的Agent ID ...,然后选择结果并执行相同的操作(选择Manager ID,然后在另一行的Agent ID中查找)

直到下端节点被获取。

我认为足够了吗?

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点,但这是最简单的。我要插入到临时表变量@result中,因为您希望从目标向上和向下移动。

首先设置您的数据:

declare @t table(ID int, AGENT_CODE varchar(10), MANAGER_CODE varchar(10), DESIGNATION varchar(20), NAME varchar(20))
insert @t values 
 (1, '0001', '0000', 'GEN MANAGER', 'STEVE') 
,(2, '0002', '0001', 'REGIONAL MANAGER', 'ALBERT') 
,(3, '0003', '0001', 'REGIONAL MANAGER', 'JOHN') 
,(4, '0004', '0002', 'UNIVERSAL TELLER', 'HENRY') 
,(5, '0005', '0003', 'UNIVERSAL TELLER', 'MEVRICK') 
,(6, '0006', '0002', 'TELLER', 'BRINGER') 
,(7, '0007', '0003', 'TELLER', 'ANTONIO')

select * from @t

创建一个表以保存结果以及我们要寻找的目标

declare @result table(ID int, AGENT_CODE varchar(10), MANAGER_CODE varchar(10), DESIGNATION varchar(20), NAME varchar(20))

declare @target int; set @target=6

将树向上修剪

;with cte as 
(
    select * from @t where id=@target
    union all
    select t.* from @t t
    join cte on cte.manager_code=t.agent_code
) 
insert @result
select * from cte

沿相反方向下移树

;with cte as 
(
    select * from @t where id=@target
    union all
    select t.* from @t t
    join cte on cte.agent_code=t.manager_code
) 
insert @result
select * from cte

输出结果:

select distinct * from @result

ID  AGENT_CODE  MANAGER_CODE    DESIGNATION       NAME
1   0001        0000            GEN MANAGER       STEVE
2   0002        0001            REGIONAL MANAGER  ALBERT
6   0006        0002            TELLER            BRINGER

答案 1 :(得分:0)

您可以尝试使用递归存储过程(为简单起见,我使用两个表):

准备工作:

CREATE TABLE TEMP
( ID INT
, AGENT_CODE VARCHAR(10)
, MANAGER_CODE VARCHAR(10)
, DESIGNATION VARCHAR(20)
, NAME VARCHAR(20));



CREATE TABLE TEMP_RETURN
( ID INT
, AGENT_CODE VARCHAR(10)
, MANAGER_CODE VARCHAR(10)
, DESIGNATION VARCHAR(20)
, NAME VARCHAR(20));



INSERT INTO TEMP VALUES  
 (1, '0001', '0000', 'GEN MANAGER', 'STEVE') 
,(2, '0002', '0001', 'REGIONAL MANAGER', 'ALBERT') 
,(3, '0003', '0001', 'REGIONAL MANAGER', 'JOHN') 
,(4, '0004', '0002', 'UNIVERSAL TELLER', 'HENRY') 
,(5, '0005', '0003', 'UNIVERSAL TELLER', 'MEVRICK') 
,(6, '0006', '0002', 'TELLER', 'BRINGER') 
,(7, '0007', '0003', 'TELLER', 'ANTONIO');

程序:

CREATE PROCEDURE HIERARCHY @AGENT_CODE AS VARCHAR(10), @MAX_LEVEL AS INTEGER, @CUR_LEVEL AS INTEGER

AS 

BEGIN

DECLARE @VAR_AGENT VARCHAR(10);    
DECLARE @VAR_MANAGER VARCHAR(10);    



SELECT @VAR_AGENT = AGENT_CODE 
     , @VAR_MANAGER = MANAGER_CODE
FROM TEMP
WHERE AGENT_CODE = @AGENT_CODE

IF @VAR_AGENT IS NOT NULL AND @CUR_LEVEL < @MAX_LEVEL
   BEGIN
       INSERT INTO TEMP_RETURN 
       SELECT * FROM TEMP
       WHERE AGENT_CODE = @AGENT_CODE;
       SET @CUR_LEVEL = @CUR_LEVEL + 1;
       EXEC HIERARCHY @VAR_MANAGER, @MAX_LEVEL, @CUR_LEVEL;
   END

END

最大级别和当前级别用于避免在表上循环的情况下发生无限循环

呼叫并显示数据:

DELETE
FROM TEMP_RETURN;


EXEC HIERARCHY @AGENT_CODE='0006', @CUR_LEVEL = 0, @MAX_LEVEL = 100;

SELECT *
FROM TEMP_RETURN
ORDER BY AGENT_CODE;

输出:

1   0001    0000    GEN MANAGER STEVE
2   0002    0001    REGIONAL MANAGER    ALBERT
6   0006    0002    TELLER  BRINGER

希望它会有所帮助:-)