Базовый рекурсивный запрос на sqlite3?

У меня есть простая таблица sqlite3, которая выглядит так:

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

Мне нужно запустить рекурсивный запрос, чтобы найти все пары данного SuperPart со всеми его субпарами. Так что скажем, что у меня есть eZ00. eZ00 является суперчастицей eZ01, а eZ01 является суперчастицей eZ03. Результат должен включать не только пары (eZ00, eZ01) и (eZ01 и eZ03), но также должен включать пару (eZ00, eZ03).

Я знаю, что есть другие способы определения таблицы, но здесь у меня нет выбора. Я знаю, что могу использовать несколько союзов, если знаю глубину своего дерева, но я не буду знать, как глубже я хочу идти. Это поможет иметь что-то вроде WITH RECURSIVE или даже просто WITH (,) AS x, но для того, что я искал, это невозможно в sqlite, правильно?

Есть ли способ сделать этот рекурсивный запрос в sqlite3?

ОБНОВЛЕНИЕ:

Когда этот вопрос был сделан, SQLite не поддерживал рекурсивные запросы, но как указано в @lunicon, SQLite теперь поддерживает рекурсивный CTE, поскольку 3.8.3 sqlite.org/lang_with.html

25
17 сент. '11 в 21:34
источник поделиться
3 ответов

Если вам посчастливилось использовать SQLite 3.8.3 или выше, тогда у вас есть доступ к рекурсивным и нерекурсивным CTE, используя WITH:

enter image description here

Благодаря lunicon, чтобы сообщить нам об этом обновлении SQLite.


В версиях до 3.8.3 SQLite не поддерживал рекурсивные CTE (или вообще CTE), поэтому не было WITH в SQLite. Поскольку вы не знаете, насколько глубоко это происходит, вы не можете использовать стандартный трюк JOIN для подделки рекурсивного CTE. Вы должны сделать это сложным способом и реализовать рекурсию в своем клиентском коде:

  • Возьмите начальную строку и идентификаторы подчасти.
  • Захватите строки и подчасти для отдельных частей.
  • Повторяйте, пока ничего не вернется.
25
17 сент. '11 в 22:06
источник

В этом SQLite Release 3.8.3 В 2014-02-03 была добавлена ​​поддержка CTE. Вот документация WITH clause Пример:

WITH RECURSIVE
cnt(x) AS (
 SELECT 1
 UNION ALL
 SELECT x+1 FROM cnt
  LIMIT 1000000
)
SELECT x FROM cnt;
7
06 марта '14 в 15:27
источник

там взломать 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
14 июля '13 в 10:27
источник

Посмотрите другие вопросы по меткам или Задайте вопрос