복붙노트

[SQL] sqlite3를에 대한 기본 재귀 쿼리?

SQL

sqlite3를에 대한 기본 재귀 쿼리?

나는 간단한의 sqlite3를 테이블이 그 다음과 같다 :

Table: Part
Part    SuperPart
wk0Z    wk00
wk06    wk02
wk07    wk02
eZ01    eZ00
eZ02    eZ00
eZ03    eZ01
eZ04    eZ01

나는 그것의 하위 부분 모두에 해당 SuperPart의 모든 쌍을 찾을 수 재귀 쿼리를 실행해야합니다. 그래서 내가 eZ00을 가정 해 봅시다. eZ00는 eZ01의 superpart이며 eZ01는 eZ03의 superpart입니다. 결과는 쌍 (eZ00, eZ01) 및 (eZ01 및 eZ03)뿐만 아니라 포함해야뿐만 아니라 쌍 (eZ00, eZ03)를 포함해야합니다.

나는 테이블을 정의하는 다른 방법이 알고,하지만 난 여기에 선택의 여지가 없다. 나는 나의 나무의 깊이를 알고 있다면 내가 여러 가지 조합을 사용할 수 있습니다 알고,하지만 난에 allways 내가 이동하는 방법을 깊이 알 수 없습니다. 그것은 WITH RECURSIVE 같은 또는 단지 WITH (,,) AS X하지만 내가 검색 한 것을 위해를하는 데 도움이 것, SQLite는에 불가능이, 맞죠?

sqlite3를이 재귀 쿼리 할 수있는 방법이 있나요?

최신 정보:

이 질문에 만들어진 경우, SQLite는 재귀 쿼리를 지원하지 않았지만, @lunicon에 의해 명시된 바와 같이, SQLite는 이제 3.8.3 sqlite.org/lang_with.html 때문에 재귀 CTE를 지원합니다

해결법

  1. ==============================

    1.만약 당신이 다음 당신이 사용하는 재귀, 비 재귀 CTE에 대한 액세스를해야합니까 높은 SQLite는 3.8.3 이상을 사용 할 수있는 좋은 방법입니다 운이 충분히 :

    만약 당신이 다음 당신이 사용하는 재귀, 비 재귀 CTE에 대한 액세스를해야합니까 높은 SQLite는 3.8.3 이상을 사용 할 수있는 좋은 방법입니다 운이 충분히 :

    우리를 해줘서 lunicon 덕분에이 SQLite는 업데이트에 대한 알고있다.

    이전 3.8.3로 버전에서 SQLite는 그래서 SQLite는에 아무런 있었다 (그 문제에 관해서는 전혀 또는 CTE를) 재귀 열팽창 계수를 지원하지 않았다. 당신이 어떻게되는지 깊이 알 수 없기 때문에, 당신은 표준이 가짜로 재귀 CTE를 트릭을 가입 할 수 없습니다. 당신은 어려운 방법을하고 클라이언트 코드에서 재귀를 구현해야한다 :

  2. ==============================

    2.2014년 2월 3일에이 SQLite는 릴리스 3.8.3에서 열팽창 계수에 대한 지원이 추가되었습니다. 여기에 절을 문서입니다 예:

    2014년 2월 3일에이 SQLite는 릴리스 3.8.3에서 열팽창 계수에 대한 지원이 추가되었습니다. 여기에 절을 문서입니다 예:

    WITH RECURSIVE
    cnt(x) AS (
     SELECT 1
     UNION ALL
     SELECT x+1 FROM cnt
      LIMIT 1000000
    )
    SELECT x FROM cnt;
    
  3. ==============================

    3.해킹이있다 http://dje.me/2011/03/26/sqlite-data-trees.html

    해킹이있다 http://dje.me/2011/03/26/sqlite-data-trees.html

    -- A method for storing and retrieving hierarchical data in sqlite3
    -- by using a trigger and a temporary table.
    -- I needed this but had trouble finding information on it.
    
    -- This is for sqlite3, it mostly won't work on anything else, however 
    -- most databases have better ways to do this anyway.
    
    PRAGMA recursive_triggers = TRUE; -- This is not possible before 3.6.18
    
    -- When creating the Node table either use a primary key or some other 
    -- identifier which the child node can reference.
    
    CREATE TABLE Node (id INTEGER PRIMARY KEY, parent INTEGER, 
        label VARCHAR(16));
    
    INSERT INTO Node (parent, label) VALUES(NULL, "root");
    INSERT INTO Node (parent, label) VALUES(1, "a");
    INSERT INTO Node (parent, label) VALUES(2, "b");
    INSERT INTO Node (parent, label) VALUES(3, "c1");
    INSERT INTO Node (parent, label) VALUES(3, "c2");
    
    -- Create the temp table, note that node is not a primary key
    -- which insures the order of the results when Node records are
    -- inserted out of order
    
    CREATE TEMP TABLE Path (node INTEGER, parent INTEGER, 
        label VARCHAR(16));
    
    CREATE TRIGGER find_path AFTER INSERT ON Path BEGIN
        INSERT INTO Path SELECT Node.* FROM Node WHERE 
            Node.id = new.parent;
    END;
    
    
    -- The flaw here is that label must be unique, so when creating
    -- the table there must be a unique reference for selection
    -- This insert sets off the trigger find_path
    
    INSERT INTO Path SELECT * FROM Node WHERE label = "c2";
    
    -- Return the hierarchy in order from "root" to "c2"
    SELECT * FROM Path ORDER BY node ASC;
    
    DROP TABLE Path; -- Important if you are staying connected
    
    
    -- To test this run:
    -- sqlite3 -init tree.sql tree.db
    
  4. ==============================

    4.샘플을 기반으로 문서와 sqlite가에 쿼리를 발견

    샘플을 기반으로 문서와 sqlite가에 쿼리를 발견

    DROP TABLE IF EXISTS parts;
    CREATE TABLE parts (part, superpart);
    INSERT INTO parts VALUES("wk0Z", "wk00");
    INSERT INTO parts VALUES("wk06", "wk02");
    INSERT INTO parts VALUES("wk07", "wk02");
    INSERT INTO parts VALUES("eZ01", "eZ00");
    INSERT INTO parts VALUES("eZ02", "eZ00");
    INSERT INTO parts VALUES("eZ03", "eZ01");
    INSERT INTO parts VALUES("eZ04", "eZ01");
    
    WITH RECURSIVE
      under_part(parent,part,level) AS (
         VALUES('?', 'eZ00', 0)
         UNION ALL
         SELECT parts.superpart, parts.part, under_part.level+1 
            FROM parts, under_part
         WHERE parts.superpart=under_part.part
      )
      SELECT SUBSTR('..........',1,level*3) || "(" || parent || ", " || part || ")" FROM under_part
      ;
    

    겠습니까 출력

      (?, eZ00)
      ...(eZ00, eZ01)
      ...(eZ00, eZ02)
      ......(eZ01, eZ03)
      ......(eZ01, eZ04)
    

    "그것은해야"예상대로

    재귀 테이블의 초기 기록은 교체 할 수 있습니다

    VALUES ((SELECT superpart FROM parts WHERE part='eZ00'), 'eZ00', 0)
    

    이 경우 부모가 전혀 없지만, 또한 초기 superpart의 부모를 얻기 위해서이다.

  5. ==============================

    5.이것은 당신이 더 복잡한 재귀 사람들을 구축 할 수 있도록 도와드립니다 우리가 1, 2로 시작하고 우리가 훨씬 유용하지 (20)에 충돌까지 1을 추가하지만, 이것으로 조금 주위를 계속 연주 시리즈를 생성, 내가 생각할 수있는 가장 기본적인 쿼리입니다

    이것은 당신이 더 복잡한 재귀 사람들을 구축 할 수 있도록 도와드립니다 우리가 1, 2로 시작하고 우리가 훨씬 유용하지 (20)에 충돌까지 1을 추가하지만, 이것으로 조금 주위를 계속 연주 시리즈를 생성, 내가 생각할 수있는 가장 기본적인 쿼리입니다

    가장 기본적인 시리즈

    WITH b(x,y) AS 
    (
        SELECT 1,2 
        UNION ALL 
        SELECT x+ 1, y + 1 
        FROM b 
        WHERE x < 20
    ) SELECT * FROM b;
    

    인쇄물

    1|2
    2|3
    3|4
    4|5
    5|6
    6|7
    7|8
    8|9
    9|10
    10|11
    11|12
    12|13
    13|14
    14|15
    15|16
    16|17
    17|18
    18|19
    19|20
    20|21
    

    여기서 피보나치 수열을 생성하는 또 다른 간단한 예는 우리는 시작 A = 0, B = 1 다음으로 이동 A = B, B = A + B 당신은 어떤 프로그래밍 언어로 할 것처럼

    피보나치 시리즈

    WITH b(x,y) AS 
    (
        SELECT 0,1 
        UNION ALL 
        SELECT y, x + y 
        FROM b 
        WHERE x < 10000
    ) select * FROM b;
    

    인쇄물

    0|1
    1|1
    1|2
    2|3
    3|5
    5|8
    8|13
    13|21
    21|34
    34|55
    55|89
    89|144
    144|233
    233|377
    377|610
    610|987
    987|1597
    1597|2584
    2584|4181
    4181|6765
    6765|10946
    10946|17711
    
  6. from https://stackoverflow.com/questions/7456957/basic-recursive-query-on-sqlite3 by cc-by-sa and MIT license