Есть база данных такого вида:
CREATE TABLE InfoTree (
ID AUTOINCLARGEINT
ParentID LARGEINT DEFAULT -1 NOT NULL,
Name WIDESTRING(1023)
);
CREATE TABLE Tags (
TagID AUTOINCLARGEINT,
TagName WIDESTRING(1023)
);
CREATE TABLE TagDependancy (
TagID LARGEINT,
ID LARGEINT
);
Первая таблица содержит древовидную структуру данных (полей там побольше конечно, но в данном случае это не важно).
Вторая таблица содержит список возможных тэгов и их уникальных идентификаторов.
И третяя таблица содержит связи между записями главной таблицы и тэгами.
Проект написан на Delphi, используется база данных Absolute Database.
Для отображения используется компонент DevExpress TcxDBTreeList. Он автоматом отрисовывает дерево по таблице InfoTree на основе ID и ParentID.
Мне дали этот проект доработать, необходимо добавить еще один TcxDBTreeList который будет показывать дерево тегов.
Это дерево всегда двухуровневое. На первом уровне у него имена тэгов (Tags.TagName), на втором уровне имена элементов основной таблицы (InfoTree.Name) соответсвующие этому тэгу.
Т.е. нужно построить таблицу c тремя полями:
ID - уникальный идентификатор
ParentID - родитель, для записей первого уровня (тэгов), он будет равен -1
Name - имя элемента, для первого уровня Tags.TagName, для второго соответсвенно InfoTree.Name
Собственно вопрос, как это оптимально сделать? Если надо структуру всех таблиц можно переделать. В планах также переход на SQLite. В базах данных и SQL я новичок, так что сильно не пинайте.
Единственное, на что у меня хватит знаний сейчас это строить это таблицу вручную, бегая по таблицам в цикле, но думаю это не самый лучший вариант. Жду советов!
Сложный запрос для создания таблицы
create table x
as
select tagid as tagid, -1 as infoid, name as name
from tags
union all
select tags.tagid, infotree.id, infotree.name
from tags, TagDependancy, InfoTree
where tags.tagid = TagDependancy.tagid
and InfoTree.id = TagDependancy.id
;
alter table x add primary key( tagid, infoid);
as
select tagid as tagid, -1 as infoid, name as name
from tags
union all
select tags.tagid, infotree.id, infotree.name
from tags, TagDependancy, InfoTree
where tags.tagid = TagDependancy.tagid
and InfoTree.id = TagDependancy.id
;
alter table x add primary key( tagid, infoid);
-
- Сообщения: 3
- Зарегистрирован: 27 июл 2009, 03:12
Видимо я не совсем ясно объяснил задачу.
Для большей наглядности вложил пример.

Дерево элементов многоуровневое. Элементам назначены некоторые теги (может быть несколько, а может вообще не быть). Внизу пример необходимого в результате дерева тэгов.
В результирующей таблице поле ID должно быть уникальным.
Для большей наглядности вложил пример.

Дерево элементов многоуровневое. Элементам назначены некоторые теги (может быть несколько, а может вообще не быть). Внизу пример необходимого в результате дерева тэгов.
В результирующей таблице поле ID должно быть уникальным.
Запрос делает то, что тебе надо. Хотя формат чуть и отличается от ожидаемого. Разбирайся... 
Смущает составной pk? Если не умеешь с ним работать, то добавь колонку id в таблицу x и заполни её уникальными значениями.
ps Испытываю некоторые трудности при составлении запросов "под заказ" для людей, в которых не видно особого желания напрягается.

Смущает составной pk? Если не умеешь с ним работать, то добавь колонку id в таблицу x и заполни её уникальными значениями.
ps Испытываю некоторые трудности при составлении запросов "под заказ" для людей, в которых не видно особого желания напрягается.

- mc-black
- Сообщения: 250
- Зарегистрирован: 08 май 2008, 16:09
- Откуда: Россия, Нижний Новгород
- Контактная информация:
Чувствую мне не превзойти мастерства Laba, т.к. сильно написано, до меня не все пока дошло))) Мне удалось добиться некоего подобия (сильно похожего на вариант Laba). Только получился запрос, а не таблица, потому как тестировал в Access, а там таблица создаваться отказалась. Запрос выглядит так:
Приложил пример базы с таблицами, данными, с сохраненным запросом. Данные в выполненном запросе вроде должны восприниматься контролом. Может кто знает, как получить уникальные значения первого поля более красивым путем, без MAX и '*', '+'?
Код: Выделить всё
SELECT Tags.TagId As TagId, -1 As Parent, Tags.TagName FROM Tags
UNION
SELECT (SELECT MAX(Tags.TagId) FROM Tags)*InfoTree.Id+Tags.TagId, Tags.TagId, InfoTree.Name
FROM InfoTree, TagDependancy, Tags
WHERE InfoTree.Id=TagDependancy.Id AND Tags.TagId=TagDependancy.TagId
ORDER BY Parent;
- Вложения
-
- tree.zip
- (9.75 КБ) 45 скачиваний
На заказ: VBA, Excel mc-black@yandex.ru
-
- Сообщения: 3
- Зарегистрирован: 27 июл 2009, 03:12
Спасибо, ваш метод работает как надо. За более "красивые" примеры тоже буду благодарен. Но главное, что работает и можно двигаться дальше!mc-black писал(а):Приложил пример базы с таблицами, данными, с сохраненным запросом. Данные в выполненном запросе вроде должны восприниматься контролом. Может кто знает, как получить уникальные значения первого поля более красивым путем, без MAX и '*', '+'?

В этой задаче решение с max() вполне рабочее. Поскольку таблицы созданы так, что мы не можем знать фактической размерности первичного ключа и мы не имеем под рукой внятного ответа на вопрос: сколько и какого рода данные в хранятся в этих таблицах.mc-black писал(а): Может кто знает, как получить уникальные значения первого поля более красивым путем, без MAX и '*', '+'?
Альтернативой max() с "*" или "+" будет использование составного pk или автоикрементной колонки.
Первый способ хорош для создания запросов "на лету", т.е. без таблицы. Недостаток - составной pk.
Второй позволяет иметь "хорошенький id" (как хочет ТС), но нужно иметь таблицу для хранения этих id. В этом варианте нужно сначала создать таблицу с автоикрементной колонкой для id, а затем сделать в неё два Insert.