2009-06-06 2 views
39

SQL Server 2000/2005/2008에서 ORACLE보다 먼저 CONNECT BY의 기능을 사용하고 싶습니다.SQL Server에서 ORACLE로 앞의 CONNECT BY 시뮬레이션

예를 들어, 구현 된, 재귀 쿼리를 구현하기 위해 나에게

+0

것은, 당신이 우리에게 약간의 테이블 구조 데이터와 무엇을 당신이하려고하는 얘기해야합니다 해야 할 것. 기존 Oracle 쿼리를 사용하면 좋은 시작이 될 것입니다 .... –

+2

@John, 내 대답에 게시 된 URL, http://www.ibm.com/developerworks/db2/library/techarticle/을 참조하십시오. dm-0510rielau/- 이것은 CONNECT BY PRIOR가 어떻게 작동하는지 보여줍니다 (나무 구조를 얻기위한 오라클 소유의 멋진 오라클 구문). (반복적 인) 공통 테이블 표현식, 즉 WITH 키워드와 동일한 효과를 얻는 방법 SQL 표준이며 IBM DB2, Microsoft SQL Server 및 릴리스 8.4의 오픈 소스 PostgreSQL 엔진에서 구현됩니다. –

+0

@Alex : 감사합니다. 나는 귀하의 게시물을보고 기사를 읽었습니다. 꽤 좋은 기사, 나는 왜 오라클 사용자가 오라클 문법을 좋아하는지 볼 수 있습니다. 더 일반적인 것처럼 표준 구문을 선호합니다. –

답변

59

은 SQL 표준 방법을 도와주세요 IBM DB2 및 SQL ServerWITH 절입니다. CONNECT BYWITH (기술적으로 재귀 CTE)으로 변환하는 한 가지 예는 this article을 참조하십시오.이 예제는 DB2 용이지만 SQL Server에서도 작동합니다.

편집 : 분명히 원래 예제에는 특정 예제가 필요합니다. URL은 이미 제공 한 IBM 사이트의 예제입니다. 테이블을 감안할 때 :

CREATE TABLE emp(empid INTEGER NOT NULL PRIMARY KEY, 
       name VARCHAR(10), 
       salary DECIMAL(9, 2), 
       mgrid INTEGER); 

mgrid 참조 직원의 관리자의 empid, 작업이다 Joan에 직접 또는 간접적으로보고하는 모든 사람의 이름을 얻는다.

SQL 서버, IBM DB2, 또는 PostgreSQL을 8.4 (뿐만 아니라 그 ;-) 가치가 무엇인지에 대한 SQL 표준에
SELECT name 
    FROM emp 
    START WITH name = 'Joan' 
    CONNECT BY PRIOR empid = mgrid 

, 완벽하게 상응하는 솔루션 대신 재귀 : 오라클에서, 그건이 CONNECT 간단합니다 질의 (더 복잡한 구문하지만, 실제로는 더 많은 힘과 유연성) :

WITH n(empid, name) AS 
    (SELECT empid, name 
    FROM emp 
    WHERE name = 'Joan' 
     UNION ALL 
    SELECT nplus1.empid, nplus1.name 
    FROM emp as nplus1, n 
    WHERE n.empid = nplus1.mgrid) 
SELECT name FROM n 

오라클의 START WITH 절은 첫 번째 중첩 SELECT, 재귀의 기본 케이스를하게는 재귀 부분 UNION 에드 될 수 있습니다 또 다른 SELECT입니다.

SQL 서버의 고유 한 맛 WITH은 당연히 MSDN에 문서화되어 있으며, 여기에는이 키워드를 사용하기위한 지침과 제한 사항 및 몇 가지 예가 나와 있습니다.

+1

예를 들어 설명해주십시오. 예. URL에서 상태 2 호주 --AusState1 --AusStae2 나는 정확한 쿼리 –

+2

내가 지적 예제를 찾고 있어요 - 은 인도와 같은 --State1 을 일부 국가를 가지고 상태 http://www.ibm.com/developerworks/db2/library/techarticle/dm-0510rielau/ 정확한 쿼리를 제공합니까? 링크를 클릭하면 무의미한 것처럼 보입니다. -) –

+0

** F ** [this url] (https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql)의 섹션이 내가 찾고있는 섹션이었습니다. –

1

이전에는 연결을 사용하지 않았지만 빠른 검색은 트리 구조에 사용 된 것으로 나타났습니다. SQL Server에서는 공통 테이블 식을 사용하여 유사한 기능을 사용합니다.

+2

예를 들어 설명해주십시오. 예. 내가 아닌 동일한 데이터 유형, 코드를 적응 이상한 문제를 가지고 상태 2 호주 --AusState1 --AusStae2 –

10

@Alex Martelli 님의 답변은 훌륭합니다! 그러나

가 내 상황을 조금 변경 ... 당신은 WHERE 절을 꺼내 경우 쿼리 함께 모든 루트 행을 반환하는 시간 ( WHERE name = 'Joan') 에 하나 개의 요소에만 작동, 그래서 수 테이블에 대한 전체 트리를 표시합니다.

테이블 정의 : 루트 1 :

CREATE TABLE [dbo].[mar_categories] ( 
    [category] int IDENTITY(1,1) NOT NULL, 
    [name]  varchar(50) NOT NULL, 
    [level]  int NOT NULL, 
    [action] int NOT NULL, 
    [parent] int NULL, 
    CONSTRAINT [XPK_mar_categories] PRIMARY KEY([category]) 
) 

(level 그대로 범주 0 레벨 인 후에 최초 루트 레벨 ...)

쿼리 :

WITH n(category, name, level, parent, concatenador) AS 
(
    SELECT category, name, level, parent, '('+CONVERT(VARCHAR (MAX), category)+' - '+CONVERT(VARCHAR (MAX), level)+')' as concatenador 
    FROM mar_categories 
    WHERE parent is null 
     UNION ALL 
    SELECT m.category, m.name, m.level, m.parent, n.concatenador+' * ('+CONVERT (VARCHAR (MAX), case when ISNULL(m.parent, 0) = 0 then 0 else m.category END)+' - '+CONVERT(VARCHAR (MAX), m.level)+')' as concatenador 
    FROM mar_categories as m, n 
    WHERE n.category = m.parent 
) 
SELECT distinct * FROM n ORDER BY concatenador asc 

이 (당신은 그냥 더 읽을 수 있도록 않았 level 필드를 연결할 필요가 없습니다)

뭔가를해야이 쿼리에 대한 응답 :

sql return

나는 누군가 도움이되기를 바랍니다! 지금

, 내가 어떻게 MySQL을이 작업을 수행하는 방법 궁금하네요 ... 당신이 세부 사항을 더 원하는 것 때문에 ^^

+0

- 은 인도와 같은 --State1 을 일부 국가를 가지고 상태 구분 기호 및 재귀 열에 ....하지만 그것을 정렬, 그냥 첫 번째 길이를 명시 적으로 정의 .... 감사합니다 도움! –

+0

구조체와 같은 구조를 얻기 위해 문자열 ('concatenador')에서 경로를 생성하는 것을 피할 수 있습니까? (예 : 각 하위 리프 값이 다른 요소에 의해 구멍없이 그룹화 되었습니까?) 오라클은'connect by' 방식으로 무료로 구축합니다. – gavenkoa