이상한 디자인 요구 사항이 있습니다. 다음은 내가 작업하고있는 예제 표입니다.여러 열의 값을 채우는 재귀적인 SQL
DECLARE @T TABLE
(
kID INT,
sCode VARCHAR(50),
kParentID INT NULL,
nNestLevel INT
)
INSERT INTO @T
SELECT 10009,'Professional Fees ',NULL ,0 UNION ALL
SELECT 10371,'Exam Room Fees ',10009 ,1 UNION ALL
SELECT 10410,'Diagnostic Tests ',NULL ,0 UNION ALL
SELECT 10011,'Pharmacy Income ',NULL ,0 UNION ALL
SELECT 10395,'Dietary Products ',NULL ,0 UNION ALL
SELECT 10053,'Outpatient Services & Treatment',10371 ,2 UNION ALL
SELECT 10055,'Canine Vaccines ',10371 ,2 UNION ALL
SELECT 10200,'Office Calls and Exams ',10371 ,2 UNION ALL
SELECT 10204,'Feline Vaccines ',10371 ,2 UNION ALL
SELECT 10205,'Ferret Vaccines ',10371 ,2 UNION ALL
SELECT 10206,'Euthanasia ',10371 ,2 UNION ALL
SELECT 10207,'Cremation & Burial ',10371 ,2 UNION ALL
SELECT 10304,'Laser Therapy ',10371 ,2 UNION ALL
SELECT 10379,'Hospitalization & Inpatient Ser',10371 ,2 UNION ALL
SELECT 10283,'Wellness Plan Diagnostics ',10410 ,1 UNION ALL
SELECT 10411,'Opthalmic Tests ',10410 ,1 UNION ALL
SELECT 10412,'Blood Pressure ',10410 ,1 UNION ALL
SELECT 10413,'Diagnostic Other Tests ',10410 ,1 UNION ALL
SELECT 10414,'EKG ',10410 ,1 UNION ALL
SELECT 10267,'In Hospital Pharmacy ',10011 ,1 UNION ALL
SELECT 10368,'Parasiticides ',10011 ,1 UNION ALL
SELECT 10383,'Outpatient Pharmacy ',10011 ,1 UNION ALL
SELECT 10013,'Prescription Diets ',10395 ,1 UNION ALL
SELECT 10021,'Non Prescription Diets ',10395 ,1 UNION ALL
SELECT 10083,'Inpatient Medical Services & Tx',10379 ,3 UNION ALL
SELECT 10201,'Outpatient Treatments ',10053 ,3 UNION ALL
SELECT 10280,'Herbal & Acupuncture Exams ',10200 ,3 UNION ALL
SELECT 10295,'Hospital Tasks Income ',10379 ,3 UNION ALL
SELECT 10308,'Distemper/Parvo ',10055 ,3 UNION ALL
SELECT 10309,'Bordetella ',10055 ,3
각 항목은 다음 레벨의 상위를 가리 킵니다. 나는이 일을 참조하고, 내가 그 테이블에 세 개의 열을 추가 할 필요가 외래 키로 아이를 사용하는 다른 테이블을 기반으로 쿼리,
열 1
쇼를 만들기 위해 필요한 것 외부 키의 SCODE,
열이
표시 일 원래의 ID가 1의 nNestLevel 또는 0 인 경우 예외를 가지고 이 될 것입니다.) 0의 nNestLevel을 가진 원래 키의 부모의 sCode는 첫 번째 열과 동일한 sCode. 3 열
0의 nNestLevel을 가지고 원래 키의 부모하여 SCODE보기, 경우 (A 예외를 에서 그에게 조금을 얻을 것이다) 원래 ID는 0의 nNestLevel에 있습니다. 은 동일한 sCode를 첫 번째 열로 다시 인쇄해야합니다.
: 나는 주위 멍청이 재귀 룩 - 업을하고 내가 그러나 문제가있다, 그것을 수행하는 방법을 이해하기 시작하고 있어요
날을 던지고 규칙에 대한 예외
루트 부모 kID가 10009 인 경우 0 대신 nNestLevel 1과 2를 사용하고 마지막 두 열의 규칙에 1을 사용합니다.
나는이 특별한 경우를 어떻게 처리해야할지 모르겠다.
내 솔루션 여기
마틴 스미스의 대답 기반으로 솔루션입니다. 몇 가지 작은 변경 사항이 있습니다. 첫 번째 CTE가 baseID를 올바르게 전달하지 못했습니다. 최종 쿼리의 select 문도 조정해야하므로 Null을 반환 할 가능성이 있기 전에 case 문이 올바른 열을 반환합니다.
;WITH R AS
(
SELECT * , 1 AS L, kID AS BasekID
FROM Accounts
UNION ALL
SELECT T.*, L+1, R.BasekID
FROM Accounts T JOIN R ON T.kID = R.kParentID
), T AS
(
SELECT BasekID AS kID,
MAX(CASE WHEN L=1 THEN sCode END) AS sCode,
MAX(CASE WHEN L=1 THEN nNestLevel END) AS nNestLevel,
MAX(CASE WHEN nNestLevel =0 THEN sCode END) AS sCode0,
MAX(CASE WHEN nNestLevel =1 THEN sCode END) AS sCode1,
MAX(CASE WHEN nNestLevel =2 THEN sCode END) AS sCode2,
MAX(CASE WHEN nNestLevel =0 THEN kID END) AS RootkID
FROM R
GROUP BY BasekID
)
SELECT kID, sCode AS Col1,
--This case statement is to handel when the rootkID is 10009, we should go up a level if it is.
CASE WHEN nNestLevel <= 1 AND RootkID <> 10009 THEN sCode
WHEN nNestLevel <= 2 AND RootkID = 10009 THEN sCode
WHEN RootkID = 10009 THEN sCode2
ELSE sCode1 END AS Col2,
CASE WHEN nNestLevel <= 0 AND RootkID <> 10009 THEN sCode
WHEN nNestLevel <= 1 AND RootkID = 10009 THEN sCode
WHEN RootkID = 10009 THEN sCode1
ELSE sCode0 END AS Col3
FROM T
당신은이를 명확히 할 수 nNestLevel이 1 또는 0이면 첫 번째 열과 동일한 sCode를 다시 인쇄해야합니다. '원래 키의 sCode가 1 인 경우 자식이 sCode를 별도의 열에 표시해야합니까? 아니면 동일한 sCode를 다시 표시해야합니까? – Wil
@Wil sCode는 문자열 설명입니다. 따라서 10283의 forgen 키가있는 경우 첫 번째 열은 "Wellness Plan Diagnostics"이고 seccond 열은 "Wellness Plan Diagnostics"가되고 세 번째 열은 "Diagnostic Tests"가됩니다. 처음 두 열은 동일하기 때문에 10283 아래에 3 개의 고유 한 이름을 갖는 수준이 충분하지 않습니다. –