powered by simpleCommunicator - 2.0.16     © 2024 Programmizd 02
Map
Форумы / SQLite [игнор отключен] [закрыт для гостей] / И снова непотопляемые иерархические каталоги
8 сообщений из 8, страница 1 из 1
И снова непотопляемые иерархические каталоги
    #40100552
tsutselola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
День добрый, форумчане!

Исходная таблица - это отсортированные значения глубины вложенности, где 0 - это родительский каталог, 1-подкаталог и т.д.
depth_id001233201233

Подскажите пожалста, как составить такую последовательность индексов?
depth_idcat_index010212.122.1.132.1.1.132.1.1.222.1.20313.123.1.133.1.1.133.1.1.2
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100562
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tsutselola,

Никак. У тебя в исходной таблице нету индексов, а значит и ссылаться не на что.

А вот если бы были, то можно было бы сделать что-то в духе:
Код: sql
1.
select row_index, depth_id, (select count(*) from t t2 where t2.depth_id=t1.depth_id and t1.row_index<=t2.row_index) as cat_index from t t1 where depth_id=0


Повторять для каждой depth_id.

А вообще, подобные задачи намного проще делать без SQL. Просто выбираешь всю таблицу а потом, уже имея у себя потоковый порядок и делать всяческую нумерацию.
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100576
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tsutselola,

показанная последовательность индексов является материализованным путём - materialized path.

Возможно, есть смысл ознакомиться с разными способами хранения иерархий в БД.
Иерархические структуры и деревья в SQL
Способы хранения деревьев в реляционных базах данных

Там описаны достоинства и недостатки разные способов. Возможно, есть смысл сразу материализованный путь использовать.


Кроме того, в некоторых СУБД есть встроенная поддержка иерархий. Например, модуль ltree в Postgresql, тип HierarchyId в Sql Server. Возможно и в Sqlite что-то есть.

Кроме того, не используется ли какая-нибудь ORM? В некоторых есть встроенная поддержка работы с иерархиями.
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100577
tsutselola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, за пояснения. Статья как-то мне попадалась уже. Там описано как таким деревом пользоваться, но не как создавать. На стороне клиента я сделал генерацию такого списка, вот думаю, раз есть CTE, может и запросом можно.
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100600
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tsutselola,

Можно. Но для этого запрос должен возвращать ОТСОРТИРОВАННЫЕ данные. А у Вас нет никакого PK и нет никакого поля для сортировки.
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100603
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p.s. таблица отсортированная сама по себе, на мой взгляд дурной тон. В SQLite еще можно считать, что есть скрытый PK в виде системного id и что под Вашеми словами "отсортированные значения" подразумевается именно он, но т.к. телепатические возможности у всех развиты в разной степени и все пользуются разными сортами кофе (а результат гадания по кофейной гуще явно зависит от сорта кофе и помола) - то лучше бы такие вещи указывать явно. Что и как "отсортировано".
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40100810
tsutselola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev,
Я выше написал что исходный столбец уже отсортирован по глубине вложения каталогов. Тут вопрос такой - можно ли по одному столбцу вложенности понять что за чем следует.
Вообще целиком все выглядит так:

Таблица
Код: sql
1.
2.
3.
4.
5.
6.
CREATE TABLE "ProjStructure" (
	"ID"	INTEGER,
	"ParentID"	INTEGER,
	"Result"	TEXT,
	PRIMARY KEY("ID" AUTOINCREMENT)
);



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
INSERT INTO ProjStructure (ParentID,Result) VALUES (0,'1');
INSERT INTO ProjStructure (ParentID,Result) VALUES (1,'1.1');
INSERT INTO ProjStructure (ParentID,Result) VALUES (2,'1.1.1');
INSERT INTO ProjStructure (ParentID,Result) VALUES (0,'2');
INSERT INTO ProjStructure (ParentID,Result) VALUES (1,'1.2');
INSERT INTO ProjStructure (ParentID,Result) VALUES (2,'1.1.2');
INSERT INTO ProjStructure (ParentID,Result) VALUES (5,'1.2.1');
INSERT INTO ProjStructure (ParentID,Result) VALUES (6,'1.1.2.1');



Вот запрос на возвращение списка. Колонка ID с отступами, а хотелось бы конечно сгенерить дерево с индексами как в колонке Result и отступами как в колонке ID.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
                    DROP TABLE IF EXISTS tmp;
                        CREATE TEMP TABLE tmp AS
                            SELECT * FROM
                                (SELECT ID,ParentID,Result,0 AS Level
                                FROM ProjStructure
                                ORDER BY ID);
                    WITH RECURSIVE cte(ID,ParentID,Level,Result) AS (
                        SELECT tmp.ID,tmp.ParentID,tmp.Level,tmp.Result FROM tmp WHERE tmp.ParentID=0
                    UNION ALL
                        SELECT tmp.ID,tmp.ParentID,cte.Level+1,tmp.Result
                        FROM tmp JOIN cte ON cte.ID=tmp.ParentID
                        ORDER BY cte.Level+1 DESC, tmp.ID
                    )
                    SELECT substr('..............................',1,Level*3) || cte.ID as ID,cte.Result FROM cte;



Результат выглядит так.
IDResult11...21.1......31.1.1......61.1.2.........81.1.2.1...51.2......71.2.142
...
Рейтинг: 0 / 0
И снова непотопляемые иерархические каталоги
    #40101564
tsutselola
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получилось добавить нумерацию корней в колонке Result2, но как от них собрать дальше материализованный путь - не могу сообразить.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
DROP TABLE IF EXISTS tmp;
CREATE TEMP TABLE tmp AS
	SELECT * FROM
		(SELECT ID,ParentID,Result,0 AS Level,NULL AS Result2
		FROM ProjStructure
		ORDER BY ID);
WITH RECURSIVE cte(ID,ParentID,Level,Result,Result2) AS (
	SELECT *,row_number() OVER(ORDER BY SLCT.ID) FROM (SELECT tmp.ID,tmp.ParentID,tmp.Level,tmp.Result FROM tmp WHERE tmp.ParentID=0) AS SLCT
UNION ALL
	SELECT tmp.ID,tmp.ParentID,cte.Level+1,tmp.Result,tmp.Result2
	FROM tmp JOIN cte ON cte.ID=tmp.ParentID
	ORDER BY cte.Level+1 DESC, tmp.ID
)
SELECT substr('..............................',1,Level*3) || cte.ID AS ID,cte.Result2,cte.Result FROM cte;



IDResult2Result111...2Null1.1......3Null1.1.1......6Null1.1.2.........8Null1.1.2.1...5Null1.2......7Null1.2.1422
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / И снова непотопляемые иерархические каталоги
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]