[SQL] 재귀는 자체 조인 할 수있는 가장 간단한 방법은?
SQL재귀는 자체 조인 할 수있는 가장 간단한 방법은?
재귀 수행하는 가장 간단한 방법은 SQL Server의 자체 조인은 무엇인가? 나는이 같은 테이블이 있습니다 :
PersonID | Initials | ParentID
1 CJ NULL
2 EB 1
3 MB 1
4 SW 2
5 YT NULL
6 IS 5
그리고 난 단지 특정의 사람과 계층 구조의 시작에 관한 기록을 얻을 수 있어야합니다. 내가 PersonID = 1로 CJ의 계층 구조를 요청 그렇다면 내가 얻을 것이다 :
PersonID | Initials | ParentID
1 CJ NULL
2 EB 1
3 MB 1
4 SW 2
그리고 EB을 위해 내가 할 것입니다 :
PersonID | Initials | ParentID
2 EB 1
4 SW 2
나는 약간의 조인 무리를 기반으로 고정 깊이 응답에서 떨어져 작업을 수행하는 방법을 생각할 수 없다이 캔에 붙어 있어요. 우리는 많은 수준이되지 않습니다하지만 난 그것을 제대로 할 싶습니다 때문에 그런 일이 이것은 할 것이다.
감사! 크리스.
해결법
-
==============================
1.
WITH q AS ( SELECT * FROM mytable WHERE ParentID IS NULL -- this condition defines the ultimate ancestors in your chain, change it as appropriate UNION ALL SELECT m.* FROM mytable m JOIN q ON m.parentID = q.PersonID ) SELECT * FROM q
주문 조건을 추가하면 트리 순서를 보존 할 수 있습니다 :
WITH q AS ( SELECT m.*, CAST(ROW_NUMBER() OVER (ORDER BY m.PersonId) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc FROM mytable m WHERE ParentID IS NULL UNION ALL SELECT m.*, q.bc + '.' + CAST(ROW_NUMBER() OVER (PARTITION BY m.ParentID ORDER BY m.PersonID) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN FROM mytable m JOIN q ON m.parentID = q.PersonID ) SELECT * FROM q ORDER BY bc
조건에 의해 순서를 변경하여 당신은 형제의 순서를 변경할 수 있습니다.
-
==============================
2.열팽창 계수를 사용하면 당신은이 방법을 수행 할 수 있습니다
열팽창 계수를 사용하면 당신은이 방법을 수행 할 수 있습니다
DECLARE @Table TABLE( PersonID INT, Initials VARCHAR(20), ParentID INT ) INSERT INTO @Table SELECT 1,'CJ',NULL INSERT INTO @Table SELECT 2,'EB',1 INSERT INTO @Table SELECT 3,'MB',1 INSERT INTO @Table SELECT 4,'SW',2 INSERT INTO @Table SELECT 5,'YT',NULL INSERT INTO @Table SELECT 6,'IS',5 DECLARE @PersonID INT SELECT @PersonID = 1 ;WITH Selects AS ( SELECT * FROM @Table WHERE PersonID = @PersonID UNION ALL SELECT t.* FROM @Table t INNER JOIN Selects s ON t.ParentID = s.PersonID ) SELECT * FROm Selects
-
==============================
3.큰 테이블에 대한 변경이있는 Quassnoi 쿼리. 다음 10 개의 차일 부모 : STR로 포맷하기 (5) ROW_NUMBER ()
큰 테이블에 대한 변경이있는 Quassnoi 쿼리. 다음 10 개의 차일 부모 : STR로 포맷하기 (5) ROW_NUMBER ()
WITH q AS ( SELECT m.*, CAST(str(ROW_NUMBER() OVER (ORDER BY m.ordernum),5) AS VARCHAR(MAX)) COLLATE Latin1_General_BIN AS bc FROM #t m WHERE ParentID =0 UNION ALL SELECT m.*, q.bc + '.' + str(ROW_NUMBER() OVER (PARTITION BY m.ParentID ORDER BY m.ordernum),5) COLLATE Latin1_General_BIN FROM #t m JOIN q ON m.parentID = q.DBID ) SELECT * FROM q ORDER BY bc
-
==============================
4.SQL 2005 이상은, 열팽창 계수가 표시의 예에 따라 이동하는 표준 방법입니다.
SQL 2005 이상은, 열팽창 계수가 표시의 예에 따라 이동하는 표준 방법입니다.
SQL 2000, 당신은 UDF를 사용하여 수행 할 수 있습니다 -
CREATE FUNCTION udfPersonAndChildren ( @PersonID int ) RETURNS @t TABLE (personid int, initials nchar(10), parentid int null) AS begin insert into @t select * from people p where personID=@PersonID while @@rowcount > 0 begin insert into @t select p.* from people p inner join @t o on p.parentid=o.personid left join @t o2 on p.personid=o2.personid where o2.personid is null end return end
(2005에서 작동하는, 그냥 그 일을의 표준 방법이 아니다. 당신이 일할 수있는 쉬운 방법은, 그것으로 실행하는 것이 발견하면 즉, 말했다)
당신이 정말로 SQL7에서이 작업을 수행해야하는 경우, 당신은 sproc에에서 위의 대략을 할 수 있지만 선택할 수없는 - SQL7은 UDF를 지원하지 않습니다.
-
==============================
5.(가) CTE의 재귀의 개념을 이해하는 데 도움이되는 다음 확인
(가) CTE의 재귀의 개념을 이해하는 데 도움이되는 다음 확인
DECLARE @startDate DATETIME, @endDate DATETIME SET @startDate = '11/10/2011' SET @endDate = '03/25/2012' ; WITH CTE AS ( SELECT YEAR(@startDate) AS 'yr', MONTH(@startDate) AS 'mm', DATENAME(mm, @startDate) AS 'mon', DATEPART(d,@startDate) AS 'dd', @startDate 'new_date' UNION ALL SELECT YEAR(new_date) AS 'yr', MONTH(new_date) AS 'mm', DATENAME(mm, new_date) AS 'mon', DATEPART(d,@startDate) AS 'dd', DATEADD(d,1,new_date) 'new_date' FROM CTE WHERE new_date < @endDate ) SELECT yr AS 'Year', mon AS 'Month', count(dd) AS 'Days' FROM CTE GROUP BY mon, yr, mm ORDER BY yr, mm OPTION (MAXRECURSION 1000)
from https://stackoverflow.com/questions/1757260/simplest-way-to-do-a-recursive-self-join by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] MySQL의 순위 그룹화 수행하는 방법 (0) | 2020.03.17 |
---|---|
[SQL] VARCHAR에 대한 장점은 (500)를 통해 VARCHAR (8000)가있다? (0) | 2020.03.17 |
[SQL] SELECT와 INSERT (0) | 2020.03.17 |
[SQL] 어떻게 비슷한 결과 및 종류의 유사성을 찾는 방법은? (0) | 2020.03.17 |
[SQL] 는 SQL에서 위해 물질을 결합 하는가? (0) | 2020.03.17 |