2016-10-01 5 views
-1

자기 조인 (부모 - 자식)이있는 고객 테이블이 있는데, 상태가 부모 또는 자식이 주문할 수있는 위치에있는 하위 고객을 반환하는 쿼리를 작성해야합니다. . 열은 비트 열이며 null입니다. 반환SQL 자체 조인 상태 승자 쿼리

결과는 다음의 행렬을 기반으로합니다 :

parent_status child_status Child is allowed to Order 
null     null   FALSE 
null     0    FALSE 
null     1    TRUE 
1     null   TRUE 
1     1    TRUE 
1     0    FALSE 
0     null   FALSE 
0     1    FALSE 
0     0    FALSE 

여기 요청한는 것에 대한 진리표, 경우에 따라 데이터

CREATE TABLE [dbo].[Customer](
    [Customer_id] [int] NOT NULL, 
    [ParentCustomer_id] [int] NULL, 
    [Name_desc] [nvarchar](50) NULL, 
    [OrderIsAllowed_status] [bit] NULL) 
GO 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(1,null,'Parent 1',1) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(2,1,'Parent 1 - Child 1',null) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(3,1,'Parent 1 - Child 2',0) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(4,1,'Parent 1 - Child 3',1) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(5,null,'Parent 2',null) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(6,5,'Parent 2 - Child 1',null) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(7,5,'Parent 2 - Child 2',1) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(8,5,'Parent 2 - Child 3',0) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(9,null,'Parent 3',0) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(10,9,'Parent 3 - Child 1',null) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(11,9,'Parent 3 - Child 2',1) 
insert Customer 
([Customer_id],[ParentCustomer_id],[Name_desc] ,[OrderIsAllowed_status]) 
values(12,9,'Parent 3 - Child 3',0) 
+0

보유하고있는 구조의 데이터 견본을 추가하십시오. 지금까지 뭐 해봤 어? – gofr1

+0

도움을 줄 수있는 정보가 충분하지 않습니다. 추가 샘플 데이터/스키마를 제공하십시오 – Merenix

+0

사과 및 일부 샘플 데이터가 스키마에 추가되었습니다. 하나만 제공하면 불필요하다고 생각한 간단한 스키마라고 생각했습니다. – Paul

답변

1

에 대한 스키마와 스크립트로 아래와 같이하십시오.

이 예제에서는 데모 용으로 테이블 변수 만 사용합니다.

declare @Customer table (Customer_id int NOT NULL, ParentCustomer_id int, OrderIsAllowed_status bit); 

insert @Customer ([Customer_id], [ParentCustomer_id], [OrderIsAllowed_status]) values 
(1,null,1), 
(2,1,null), 
(3,1,0), 
(4,1,1), 
(5,null,null), 
(6,5,null), 
(7,5,1), 
(8,5,0), 
(9,null,0), 
(10,9,null), 
(11,9,1), 
(12,9,0); 

select 
child.Customer_id, 
child.ParentCustomer_id, 
(case 
when child.ParentCustomer_id is null then 'Parent '+ cast(child.Customer_id as varchar) 
else concat('Parent ',parent.Customer_id,' - Child ',child.Customer_id) 
end) as Name_desc, 
parent.OrderIsAllowed_status as parent_status, 
child.OrderIsAllowed_status as child_status, 
cast(case 
    when child.OrderIsAllowed_status = 1 and parent.OrderIsAllowed_status = 1 then 1 
    when child.OrderIsAllowed_status = 1 and parent.OrderIsAllowed_status is null then 1 
    when child.OrderIsAllowed_status is null and parent.OrderIsAllowed_status = 1 then 1 
    else 0 
    end as bit) as [Child is allowed to Order] 
from @Customer child 
left join @Customer parent on (child.ParentCustomer_id = parent.Customer_id); 
+0

감사 대답 : 나는 Parent_IsAllowed \t, C로 다음 p.Customer_id \t ..select 문, p.Name_desc \t, p.OrderIsAllowed_status 문제 일 것입니다 무슨 ... 내 자신의 queston 답변을 시도했다. 는 내부가 c.ParentCustomer_id p.customer_id = ON 고객 C \t 가입 고객 P로부터 CUSTOMER_ID \t, c.ParentCustomer_id \t, c.Name_desc \t, c.OrderIsAllowed_status \t \t (p.OrderIsAll owed_status가 null c.OrderIsAllowed_status = 1) 또는 \t (p.OrderIsAllowed_status = 1 c.OrderIsAllowed_status는 \t 또는 (p.OrderIsAllowed_status = 1) null이며 c.OrderIsAllowed_status = 1) – Paul

+1

는 SQL과 의도이면 [그 아이가 주문할 수있는] 아이들 만 얻는 것이 사실이라면 그 SQL은 잘못이 아닙니다. 개인적으로 다 대일 관계를 맺었지만 나는 "많은 것"을에 넣고 "하나"에 그것에 합류했습니다. – LukStorms

1

당신은 재귀 CTE 사용할 수 있습니다

;WITH rec AS (
    SELECT Customer_id, 
      ParentCustomer_id, 
      Name_desc, 
      OrderIsAllowed_status, 
      CAST(NULL AS bit) as parent_status, 
      1 as [Level] 
    FROM #Customer c 
    WHERE ParentCustomer_id IS NULL 
    UNION ALL 
    SELECT c.Customer_id, 
      c.ParentCustomer_id, 
      c.Name_desc, 
      c.OrderIsAllowed_status, 
      r.OrderIsAllowed_status, 
      r.[Level]+ 1 
    FROM rec r 
    INNER JOIN #Customer c 
     ON c.ParentCustomer_id = r.Customer_id 
) 

SELECT r.Customer_id, 
     r.ParentCustomer_id, 
     r.Name_desc, 
     r.OrderIsAllowed_status, 
     rs.[Child is allowed to Order] 
FROM rec r 
INNER JOIN #rules rs 
    ON COALESCE(r.[OrderIsAllowed_status],2) = COALESCE(rs.child_status,2) 
     AND COALESCE(r.parent_status,2) = COALESCE(rs.parent_status,2) 
WHERE r.ParentCustomer_id IS NOT NULL 

출력 :

Customer_id ParentCustomer_id Name_desc   OrderIsAllowed_status Child is allowed to Order 
10   9     Parent 3 - Child 1 NULL     FALSE 
11   9     Parent 3 - Child 2 1      FALSE 
12   9     Parent 3 - Child 3 0      FALSE 
6   5     Parent 2 - Child 1 NULL     FALSE 
7   5     Parent 2 - Child 2 1      TRUE 
8   5     Parent 2 - Child 3 0      FALSE 
2   1     Parent 1 - Child 1 NULL     TRUE 
3   1     Parent 1 - Child 2 0      FALSE 
4   1     Parent 1 - Child 3 1      TRUE 

내가 사용했던이 테이블 :

CREATE TABLE #Customer (
    [Customer_id] [int] NOT NULL, 
    [ParentCustomer_id] [int] NULL, 
    [Name_desc] [nvarchar](50) NULL, 
    [OrderIsAllowed_status] [bit] NULL 
) 

INSERT INTO #Customer VALUES 
(1,null,'Parent 1',1), 
(2,1,'Parent 1 - Child 1',null), 
(3,1,'Parent 1 - Child 2',0), 
(4,1,'Parent 1 - Child 3',1), 
(5,null,'Parent 2',null), 
(6,5,'Parent 2 - Child 1',null), 
(7,5,'Parent 2 - Child 2',1), 
(8,5,'Parent 2 - Child 3',0), 
(9,null,'Parent 3',0), 
(10,9,'Parent 3 - Child 1',null), 
(11,9,'Parent 3 - Child 2',1), 
(12,9,'Parent 3 - Child 3',0) 

CREATE TABLE #rules (
    parent_status bit NULL, 
    child_status bit NULL, 
    [Child is allowed to Order] nvarchar(5) NULL 
) 

INSERT INTO #rules VALUES 
(null, null, 'FALSE'), 
(null, 0, 'FALSE'), 
(null, 1, 'TRUE'), 
(1, null, 'TRUE'), 
(1, 1, 'TRUE'), 
(1, 0, 'FALSE'), 
(0, null, 'FALSE'), 
(0, 1, 'FALSE'), 
(0, 0, 'FALSE') 
0

나는 내 자신의 질문에 대답하려고했습니다 ... 무엇이 잘못 됐을까요? 그는 다음과 같이 지시합니다. 주문을 허용 한 아동 고객 만 반환하려고하는 경우 다음과 같이합니다.

select p.Customer_id 
    ,p.Name_desc 
    ,p.OrderIsAllowed_status as Parent_IsAllowed 
    ,c.Customer_id 
    ,c.ParentCustomer_id 
    ,c.Name_desc 
    ,c.OrderIsAllowed_status  
from Customer p 
inner join Customer c 
    on p.customer_id = c.ParentCustomer_id 
where 
    (p.OrderIsAllowed_status is null and c.OrderIsAllowed_status =1) 
    or(p.OrderIsAllowed_status = 1 and c.OrderIsAllowed_status is null) 
    or (p.OrderIsAllowed_status = 1 and c.OrderIsAllowed_status = 1) 
+1

'grandparent-parent-child'가 있다면 이것은 작동하지 않을 것입니다. – gofr1

+0

감사합니다 - 나는이 시나리오를 놓쳤습니다. 나의 경우에 테이블의 역사적인 사용법은 한 계층의 계층 구조만을 가졌지 만 부모님은 맞습니다. 원래 디자인을 고려해야합니다. – Paul

+0

나의 기쁨! :) – gofr1