Форум: "Потрепаться";
Текущий архив: 2003.12.26;
Скачать: [xml.tar.bz2];
ВнизПомогите написать 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c