![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Группировка записей в НД
JS2 © (2009-10-22 11:04:00)SELECT'ом формирую НД. Получается, к примеру:
item_id | group_id
------------------
2 16
5 16
6 16
17 16
21 22
22 22
36 7
74 7
P.S. ORDER BY group_id
Нужно сделать следующие: пройти по всему набору группируя в сроку Item_id с
одинаковыми group_id + вывод, т.е. для данного примера должно быть так:
1 - ShowMessage -> 2,5,6,17
2 - ShowMessage -> 21,22
3 - ShowMessage -> 36,74
Как бы это написать алгоритм пограмотнее?
JS2 (2009-10-22 12:03:00) [1]
> если датасет пустой
А если предварительно добавить проверку на пустой датасет имеет ли смысл проверять ItemIds перед Delete(ItemIds, 1, 1) и перед последним ShowMessage.
palva (2009-10-22 11:54:00) [2]
> query_ByField.First;
> GroupID := field_group_id.AsInteger;
Здесь также будут неприятности, если датасет пустой.
palva (2009-10-22 11:48:00) [3]
> if ItemIds[1] = ',' then
> Delete(ItemIds, 1, 1);
Вот это непонятно зачем нужно. Тем более, что ItemIds может быть пустой строкой и проверка первого символа может привести к неприятностям.
Перед последним ShowMessage полезно проверить, что строка не пустая. Иначе будет ненужный вывод пустой строки в случае пустого множества записей.
JS2 (2009-10-22 11:32:00) [4]
> palva ©
кажется, я так и делал. Вот код:
procedure Tform_Main.Button1Click(Sender: TObject);
var
ItemIds: string;
GroupID: Integer;
field_group_id, field_item_id: TField;
begin
with DMConnection do
begin
field_group_id := query_ByField.FieldByName('group_id');
field_item_id := query_ByField.FieldByName('item_id');
query_ByField.First;
GroupID := field_group_id.AsInteger;
ItemIds := '';
while not query_ByField.Eof do
begin
if field_group_id.AsInteger = GroupID then
ItemIds := ItemIds + ', '
else
begin
ShowMessage(ItemIds);
ItemIds := '';
end;
ItemIds := ItemIds + field_item_id.AsString;
GroupId := field_group_id.AsInteger;
if ItemIds[1] = ',' then
Delete(ItemIds, 1, 1);
query_ByField.Next;
end;
ShowMessage(ItemIds);
end;
end;
Посмотрите может есть какие-то упущения?
palva (2009-10-22 11:24:00) [5]В разных вариантах подобная задача очень часто встречается. Полезно придерживаться некоторого шаблона, чтобы в следующий раз не думать.
Сохраняйте значение group_id в отдельной переменной, и на каждой итерации у вас будет значение group_id на предыдущей итерации.
Если значение group_id на очередной итерации то же самой, что и на предыдущей, то накапливайте item_id в строке для вывода. Если оно другое, то выводите строку в ShowMessage и очищайте ее.
По особому должна быть выполнена самая первая итерация (не выводить ShowMessage), а также следует выполнить дополнительные действия после окончания цикла - выполнить ShowMessage, если строка вывода не пустая.
Л.Д. (2009-10-22 11:10:00) [6]
> Так ты же его уже написал
вообщем-то написал, но не совсем удачный, как мне кажется
JS2 (2009-10-22 11:10:00) [7]Удалено модератором
Sergey13 (2009-10-22 11:08:00) [8]> [0] JS2 (22.10.09 11:04)
> Как бы это написать алгоритм пограмотнее?
Так ты же его уже написал
> пройти по всему набору группируя в сроку Item_id с одинаковыми group_id + вывод