Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.12.26;
Скачать: CL | DM;

Вниз

Помогите написать Select   Найти похожие ветки 

 
SergP ©   (2003-12-01 22:46) [0]

Имеется таблица с полями:
id, parent, order, name
первые три поля - целые числа, последнее (name) - строка.
name - у меня там хранится допустим название форума (это мне нужно для клиента одного "хитрого" форума)
id - в принципе понятно из названия.
В parent хранится (0 - для форума, id родителя для субфорума). Макс. уровень вложенности - 1.
поле order используется для порядка отображения форумов. Первым отображается тот у которого order меньше. Если же order у нескольки записей одинаковый, то порядок отображения задается id"ом.

Нужно из таблицы выбрать все записи в таком порядке:
форум 1
субфорум 1.1
....
субфорум 1.N
форум 2
...
форум N

Вот никак не могу придумать как мне написать Select для этого.
Может кто-нить поможет? А то у мне кажется что нужно делать сложный запрос (или вложенный или с объединением). А как попроще ну никак не могу придумать... Хотя на вид вроде бы простая задача...


 
VictorT ©   (2003-12-01 23:13) [1]

Кажись та же проблема:
http://deep.webm.ru/forum/reply.php?num=1.6&id=655


 
SergP ©   (2003-12-01 23:30) [2]


> VictorT © (01.12.03 23:13) [1]
> Кажись та же проблема:
> http://deep.webm.ru/forum/reply.php?num=1.6&id=655


Немного не та... Но все равно тоже интерестная...


 
Petr V. Abramov ©   (2003-12-01 23:46) [3]

Вы б хоть СУБД объявили...


 
SergP ©   (2003-12-02 00:09) [4]


> Petr V. Abramov © (01.12.03 23:46) [3]
> Вы б хоть СУБД объявили...


Лучше конечно если я это смогу сделать в самом клиенте (ADO, провайдер Microsoft.Jet.OLEDB.4.0).

Можно конечно (но этот вариант мне не очень нравится) если это будет делать php скрипт на сервере (СУБД MySQL ver 4.0.15)


 
ИдиотЪ ©   (2003-12-02 01:52) [5]

сделай производной поле id.parent - строковое, а потом отсортируешь по нему
(что в голову пришло)


 
SergP ©   (2003-12-02 02:16) [6]


> ИдиотЪ © (02.12.03 01:52) [5]
> сделай производной поле id.parent - строковое, а потом отсортируешь
> по нему
> (что в голову пришло)


Дык ведь id, parent - это не одно поле а два, да и order нужно учесть.

Вобщем еще раз об условии:
Группы субфорумов должны идти сразу после родительского форума.
Т.е. сначала идет запись (родитель) с опреденным id, а затем группа записей у которых parent равен id"у родителя.
А уже после порядок расположения групп родитель+"дети" относительно других таких же групп, а также порядок расположения "детей" конкретного родителя должно определяться order"ом, а при его равенстве id"ом...


 
Ihor Osov'yak ©   (2003-12-02 02:20) [7]

селектом, имхо, не выйдет.
Похожие вещи в IB я делал с помощью хранимых процедур..
В MSSql наверно можно с помощью курсоров..

Да, разве что как [5] ИдиотЪ © (02.12.03 01:52) - либо вычисляемое на стороне сервера поле, либо через представление.. Соотв., с order by ..

А на клиенте - в чем там проблема? Делай, что душе угодно.. Только немного думай, чобы поменьше запросов гонять..


 
SergP ©   (2003-12-02 02:51) [8]

Пока только такая мысль есть:

select id,parent,name
from
(
select b.id as k_id, b.order as s_order, a.id, a.order, a.parent, a.name
from table as a, table as b
where (a.parent=b.id) or (a.id=b.id)
)
order by k_order, k_id, parent, order, id

Сильно мутно правда. Да и не знаю пока будет ли работать. Это только мысль. Дело в том что во вложеном select"е придется выбирать данные типа из двух таблиц, которые на самом деле одна и та же таблица, да и насчет AS"ов я не совсем уверен в правильности написания.

Может кто предложит что попроще?


 
ИдиотЪ ©   (2003-12-02 03:01) [9]

SergP ©
cделай вычисляемое поле или функцию напиши, примерно
select iif(parent is null,id,parent)+"."+iif(parent is null,0,id) as id_par, *
...
order by id_par

за синтаксис не отвечаю, давно не баловался потому как


 
ИдиотЪ ©   (2003-12-02 03:05) [10]

т.е. самое можно двумя селектами с объединением сделать, догадайся, как )
вот если уровень вложения больше, тут надо еще подумать


 
SergP ©   (2003-12-02 08:54) [11]


> ИдиотЪ © (02.12.03 03:05) [10]
> т.е. самое можно двумя селектами с объединением сделать,
> догадайся, как )
> вот если уровень вложения больше, тут надо еще подумать


Уровень вложения на том форуме не более 1.
Да и тот select что я написал выше в своем сообщении можно записать в виде простого select"а без вложений:

select a.id, a.order, a.parent, a.name
from table as a, table as b
where (a.parent=b.id) or (a.id=b.id)
order by b.order, b.id, a.parent, a.order, a.id

Вот только не знаю пройдет ли такое: from table as a, table as b
т.е. как я писал выше выбор из одной таблицы как будто из двух.


> ИдиотЪ © (02.12.03 03:05) [10]
> т.е. самое можно двумя селектами с объединением сделать,
> догадайся, как )
> вот если уровень вложения больше, тут надо еще подумать


Думал над таким и пршел к выводу что даже в случае с объединением один подзапрос все равно должен быть либо вложенным либо .... Дело в том что порядок расположения дочерних форумов определяется не только значениями полей их записей, а также значением полей записей их родительских форумов.

Кстати может кто подскажет можно ли все таки делать такое и будет ли оно нормально работать:
from table as a, table as b ? Если да, то меня в принципе устраивает мое собственное решение...


 
Vitaly ©   (2003-12-02 09:00) [12]

конечно, будет.


 
AbrosimovA ©   (2003-12-02 09:07) [13]

По-моему, в Дельфи, перед тем как компилировать проект, можно непосредственно проверить работу SQL-запроса и по необходимости его подредактировать.


 
SergP ©   (2003-12-02 12:30) [14]


> AbrosimovA © (02.12.03 09:07) [13]
> По-моему, в Дельфи, перед тем как компилировать проект,
> можно непосредственно проверить работу SQL-запроса и по
> необходимости его подредактировать.


Уже пробовал. Все работает почти так как нужно, за исключением того что некоторые записи (соответствующие дочерним форумам) двоятся...(причем в разных местах. Первые копии таких запией стоят на тех местах что и требовалось, а вторые в местах определяемых скорее всего их order и id Что делать? Как от них избавиться?


 
SergP ©   (2003-12-02 12:37) [15]

Хм. После того как запостил предыдущее сообщение, сразу понял что нужно переделать. Сделал так:

select a.id, a.order, a.parent, a.name
from table as a, table as b
where (a.parent=b.id) or ((a.id=b.id) and (b.parent=0))
order by b.order, b.id, a.parent, a.order, a.id

Теперь работает нормально. Все. вопрос отменяется...


 
Вася Добрый   (2003-12-02 13:03) [16]

У тебя ИХМО вообще одно лишнее поле order. Убери его и не парься!
ID - номер форума, parent - порядковый номер, у родителя он всегда 0, дальше по возрастанию и всё, примитивный select с одним order"ом даст тебе щастье


 
SergP ©   (2003-12-02 13:16) [17]


> Вася Добрый (02.12.03 13:03) [16]
> У тебя ИХМО вообще одно лишнее поле order. Убери его и не
> парься!
> ID - номер форума, parent - порядковый номер, у родителя
> он всегда 0, дальше по возрастанию и всё, примитивный select
> с одним order"ом даст тебе щастье


Нельзя его убрать... Оно есть в базах самого форума и также имеет отношение к сортировке при отображении списка форумов. Поэтому чтобы в проге-клиенте порядок отображения был такой же как и на сайте я его тоже переношу в базу на лок. компе. И поэтому его приходится юзать. в принципе я могу вообще ничего не сортировать, а сделать
select * from table
но это будет не красиво. Типа на сайте по одному а в проге по другому....


 
Soft ©   (2003-12-04 01:46) [18]

Даю процедуру, которая строит дерево папок(нетрудно переделать в форумов) с неограниченным чистом иерархии.

Есть таблица папки, которая создает в программе виртуальную файловую систему с полями:

ID: идентификатор
FOLDERNAME:имя папки
FOLDERDEPENDENCE:Id предка данной папки
FOLDERFIXING: тип папки(был необходим для внутреннего применения)

Первая папка(id:0) ссылается на саму себя.

Код Sql

CREATE TABLE FOLDERS (
ID INTEGER NOT NULL,
FOLDERNAME VARCHAR(255),
FOLDERDEPENDENCE INTEGER DEFAULT null,
FOLDERFIXING INTEGER DEFAULT 0
);

ALTER TABLE FOLDERS ADD PRIMARY KEY (ID);
ALTER TABLE FOLDERS ADD CONSTRAINT FK_FOLDERS FOREIGN KEY (FOLDERDEPENDENCE) REFERENCES FOLDERS (ID) ON DELETE CASCADE ON UPDATE CASCADE;

Код процедуры

Procedure LoadFoldersToList(var LoadFolderQuery:TSDQuery;var LoadFolderTree:TTreeView);
var Node: TTreeNode;
var index:integer;
begin

LoadFolderTree.Items.Clear;
LoadFolderQuery.Active:=False;
LoadFolderQuery.SQL.Clear;
LoadFolderQuery.SQL.Add("select * from folders order by folderdependence,id;");
LoadFolderQuery.Active:=True;
//создаем основной корень
if (LoadFolderQuery.Locate("folderfixing",3,[loCaseInsensitive])) then
begin
Node:=LoadFolderTree.Items.Insert(nil,LoadFolderQuery.FieldByName("foldername").AsString);
Node.ImageIndex:=LoadFolderQuery.FieldByName("folderfixing").AsInteger;
Node.StateIndex:=LoadFolderQuery.FieldByName("id").AsInteger;
Node.SelectedIndex:=LoadFolderQuery.FieldByName("folderfixing").AsInteger;
end;
LoadFolderQuery.Delete;

if (LoadFolderTree.Items.Count>0) then
begin
LoadFolderQuery.First;
while not LoadFolderQuery.Eof do
begin
index:=0;
while ((index<LoadFolderTree.Items.Count) and (LoadFolderQuery.FieldByName("folderdependence").AsInteger<>LoadFolderTree.Items[index].StateIndex)) do inc(index);
Node:=LoadFolderTree.Items.AddChild(LoadFolderTree.Items[index],LoadFolderQuery.FieldByName("foldername").AsString);
Node.ImageIndex:=LoadFolderQuery.FieldByName("folderfixing").AsInteger;
Node.StateIndex:=LoadFolderQuery.FieldByName("id").AsInteger;
Node.SelectedIndex:=LoadFolderQuery.FieldByName("folderfixing").AsInteger;
LoadFolderQuery.Delete;
end;
end;
LoadFolderQuery.Active:=False;

end;



Страницы: 1 вся ветка

Текущий архив: 2003.12.26;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.022 c
3-86277
dimm22
2003-12-03 08:37
2003.12.26
Посоветуйте толковую книгу по MSSQL, с описанием компонент


3-86310
visnuk
2003-12-01 15:37
2003.12.26
Перенос БД на другой компьютер


14-86512
raymond
2003-12-04 12:05
2003.12.26
Музыка и программирование


1-86345
Артем
2003-12-12 16:29
2003.12.26
Анимированная кнопка через обработку события onTimer


1-86405
Markus
2003-12-14 23:42
2003.12.26
компонент TstringGrid