powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите написать сложный древовидный запрос для Sybase SA 12
10 сообщений из 10, страница 1 из 1
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37333808
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi All,

Sybase SA 12.0.1

Есть таблица - спр. Организаций, где данные организаций хранятся и отображаются в виде дерева, что бы была видна иерархия организаций:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create table dba.ORGANIZATION(
ID integer not null,
SUBID integer null,
ORGANIZNAME char( 100 ) not null,
primary key (ID));

ALTER TABLE dba.ORGANIZATION ADD FOREIGN KEY "FK_ORGANIZATION_SUBITEM" ("SUBID") 
REFERENCES dba.ORGANIZATION("ID");

В таблице есть такие данные:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 1 , null, 'Организация 1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 2 ,  1 , 'Отдел 1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 3 ,  1 , 'Отдел 2');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 4 ,  1 , 'Отдел 3');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 5 ,  3 , 'Отдел 2.1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 6 ,  3 , 'Отдел 2.2');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 7 ,  2 , 'Отдел 1.1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 8 ,  2 , 'Отдел 1.2');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 9 ,  8 , 'Отдел 1.2.1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 10  , 9 , 'Отдел 1.2.1.1');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 11 , null, 'Организация 2');
insert into dba.ORGANIZATION(ID, SUBID, ORGANIZNAME) values( 12 ,  11 , 'Подразделение 1');


Есть другая таблица - спр. Работников. Каждому работнику указывается в какой организации (отделе, подразделении) он работает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create table dba.WORKER(
ID integer not null,
WORKENAME char( 35 ) not null,
ORGANIZCODE integer not null,
primary key (ID));

ALTER TABLE dba.WORKER ADD NOT NULL FOREIGN KEY "FK_ORGANIZATION_ORGANIZCODE" ("ORGANIZCODE")
    REFERENCES dba.ORGANIZATION("ID")

В таблице есть скажем такие данные:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 1 ,  2 , 'Работник 1 Отдел 1');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 2 ,  2 , 'Работник 2 Отдел 1');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 3 ,  2 , 'Работник 3 Отдел 1');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 4 ,  3 , 'Работник 1 Отдел 2');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 5 ,  3 , 'Работник 2 Отдел 2');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 6 ,  6 , 'Работник 1 Отдел 2.2');
insert into dba.WORKER(ID, ORGANIZCODE, WORKERNAME) values( 7 ,  11 , 'Работник 1 Организация 2');
То есть для каждой организации (отдела, подразделения) в этой таблице может быть один или несколько работников, а может быть ни одного.

Мне нужно составить запрос или в крайнем случае создать хранимую процедуру, что бы она вернула данных спр. Работников в таком виде (две колонки с наименованиями):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Название организации              ФИО работника

 Главная орг.                                              
   отдел 1                                 
                                работник 1 отдела  1
                                работник 2 отдела  1
                                работник 3 отдела  1
   отдел 2                                 
                                работник 1 отдела  2
                                работник 2 отдела  2                                                 
     отдел 2.2                             
                                работник 1 отдела  2.2
 Организация 2
                                работник 1 организация 2

Или в таком виде (т.е. одна колонка с наименованиями):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Название организации/ФИО работника

 Главная орг.                                              
   отдел 1                                 
     работник 1 отдела  1
     работник 2 отдела  1
     работник 3 отдела  1
   отдел 2                                 
     работник 1 отдела  2
     работник 2 отдела  2                                                 
     отдел 2.2                             
       работник 1 отдела  2.2
 Организация 2
    работник 1 организация 2

То есть данные работников отображаются в виде иерархии их организаций и при этом если у организации нет работника, то она в этом запросе не должна отображаться.

Уже всю голову сломал, думая как можно сделать такой запрос, помогите пожалуйста.
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37333817
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще забыл добавить, что запрос или хранимая процедура, которая будет возвращать данные спр. Работников обязательно должна возвращать значения полей ID и SUBID (скорее всего заново сгенеренных), что бы можно было из этой выборки на клиенте построить дерево в компоненте типа DBTreeView.
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37333843
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4Уже всю голову сломал, думая как можно сделать такой запрос, помогите пожалуйста.А не надо делать такой запрос.
Сделай просто:
Код: plaintext
1.
2.
3.
 select ORGANIZNAME, WORKERNAME
from ORGANIZATION o
join WORKER w on w.ORGANIZCODE=o.ID
order by  1 , 2 
А в клиенте просто бежишь по резалтсету и проверяешь: как в первой колонке значение поменялось, значит надо сделать новую ветку, пока значение первой колонки не меняется делаешь новый лист на последней созданной ветке.
Все просто и легко.
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37333982
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlStalker4Уже всю голову сломал, думая как можно сделать такой запрос, помогите пожалуйста.А не надо делать такой запрос.
Сделай просто:
Код: plaintext
1.
2.
3.
 select ORGANIZNAME, WORKERNAME
from ORGANIZATION o
join WORKER w on w.ORGANIZCODE=o.ID
order by  1 , 2 
А в клиенте просто бежишь по резалтсету и проверяешь: как в первой колонке значение поменялось, значит надо сделать новую ветку, пока значение первой колонки не меняется делаешь новый лист на последней созданной ветке.
Все просто и легко.Это не годится, так как результат после такой пробежки не будет соответствовать иерархии организаций и в самом результате все ветки будут первого уровня с одной вложенностью - фактически это получиться группировка по организации.
А мне нужен именно вывод данных спр. работников в соответствии с иерархией их организаций.
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37334083
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4А мне нужен именно вывод данных спр. работников в соответствии с иерархией их организаций.
Это смотрел?
http://www.sql.ru/faq/faq_topic.aspx?fid=203
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37334094
BirdIV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллега не судите строго, два ночи все таки. Думаю это вам подойдет.
(Такой запрос не учитывает Stalker4если у организации нет работника, то она в этом запросе не должна отображаться) Это допилите сами.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select  O.ID,O.SUBID,  ORGANIZNAME ORGANIZ,
case 
when O.SUBID is null or (O.ID=O.SUBID and O.SUBID is not null and W.ORGANIZCODE=O.SUBID) then W.WORKERNAME
when O.SUBID is null then ''
when O.SUBID > 0   then  W.WORKERNAME
end WORKS
into _aaa
from ORGANIZATION O
left  join WORKER W on  W.ORGANIZCODE=O.ID

Код: plaintext
1.
2.
3.
4.
create table _bbb
(ID int not null,
SUBID int null,
NAME char( 100 ) null,
WORKER char( 100 ) null)

Код: plaintext
1.
2.
3.
4.
5.
6.
insert _bbb (ID,SUBID,NAME,WORKER)
select distinct ID,SUBID,ORGANIZ, '' from _aaa
where SUBID is null or (SUBID in (select ID from _aaa)  and WORKS is not null)

insert _bbb (ID,SUBID,NAME,WORKER)
select distinct ID,SUBID,'', WORKS from _aaa
where SUBID is null or (SUBID in (select ID from _aaa)  and WORKS is not null)

Код: plaintext
1.
select distinct * from _bbb where NAME is not null and WORKER is not null
order by  1 , 2 
попробовал на ASE 12/5/3 правда.
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37334185
ARTURV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4,
Обратите внимание на классические алгоритмы работы с деревьями. Почитайте, например, http://www.getinfo.ru/article610.html
Кроме того, обратите внимание на рекурсивные запросы -[ WITH temporary-views ] SELECT
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37335556
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 02.07.2011 18:44, Stalker4 wrote:

Учтите, что сделать обход дерева чисто на SQL, одним запросом -- невозможно.
Нужно писать хранимую процедуру. Алгоритмы обхода дерева хорошо известны и
описаны, можете поглядеть напр. на algolist.ru. На TSQL реализуются достаточно
легко.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37335561
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 04.07.2011 16:14, MasterZiv wrote:

> Учтите, что сделать обход дерева чисто на SQL, одним запросом -- невозможно.

Извините, написал про стандартный SQL и ASE, не увидел, что там ASA.
В ASA с запросом с WITH можно обойти дерево (правда это уже не
совсем SQL).
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Помогите написать сложный древовидный запрос для Sybase SA 12
    #37335961
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlStalker4А мне нужен именно вывод данных спр. работников в соответствии с иерархией их организаций.
Это смотрел?
http://www.sql.ru/faq/faq_topic.aspx?fid=203
Рекурсивные запросы я конечно смотрел.
И если бы речь шла о простой древовидной выборке, то этот вариант я бы и
использовал.
Но тут есть пара сложностей, которые я не знаю как решить в рамках этого
рекурсивного запроса:

1) Так как в одной организации может быть несколько работников, то в
конечной выборке в общем варианте может быть несколько строк с одинаковым
кодом организации (ORGANIZATION.ID или ORGANIZCODE), а ведь это поле является
ПК в спр. организаций по которому строиться дерево организацией. То есть это
поле не должно дублироваться в конечной выборке. Что бы это исправить, в
конечной выборке все строки с одинаковой организацией должны стать детьми
одной строки с дублирующейся организацией либо в выборку должна быть
добавлена фиктивная строка с дублирующейся организацией и все такие же
дублирующие организации должны стать ее детьми плюс должны быть сформированы новые поля ID и SUBID по которым будет строиться новое дерево.

2) Как я уже написал выше "данные работников отображаются в виде
иерархии их организаций и при этом если у организации нет работника, то
она в этом запросе не должна отображаться".
Тут есть одно маленькое уточнение: если у самой организации нет работника, но
он есть у одного из ее детей, то такая организация должна отображаться
в конечной выборке.

В прочем оба эти момента ИМНО вполне отражены в тех данных и в конечных
ожидаемых результатах выборки, которые я привел в первом своем сообщении.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Помогите написать сложный древовидный запрос для Sybase SA 12
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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