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

Вниз

Агрегирование в ClientDataSet   Найти похожие ветки 

 
Lexer ©   (2005-05-12 14:09) [0]

У меня к одному Query подключены 4 ClientDataSet, подскажите как в ClientDataSet группировать данные.
Например запрос:
Select
id_balance_org,
id_org,
id_dep
id_employee,
sum_1,
sum_2
from my_table


в первом "клиенте" надо показать
Select
id_balance_org,
sum(sum_1),
sum(sum_2)
from my_table
group by id_balance_org


во втором сгруппировать по id_org и т.д....


 
ANB ©   (2005-05-12 15:45) [1]

А смысл подключения ? Группировку ты уже написал.


 
Lexer ©   (2005-05-12 16:24) [2]

Поверьте смысл есть!
Запрос выполняется больше 1 мин.


 
AlexO ©   (2005-05-12 18:01) [3]

Если ты о показе данных, агрегирование в ClientDataSet ничего тебе не даст. Оно предназначено для подсчета сумм групп, а не для показа в таблице.


 
Lexer ©   (2005-05-12 18:15) [4]

AlexO - я уже это увидел (
жаль..


 
Polevi ©   (2005-05-13 09:09) [5]

>Lexer ©   (12.05.05 18:15) [4]
у меня есть свое решение, могу выслать


 
Polevi ©   (2005-05-13 09:15) [6]

unit grpBy;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, DbClient, Db, ADODB, Provider;

type
 TAggType=(atSum);
 TGroupBy=class
 private
   FDataset:TClientDataset;
   FGroupByFields:string;
   FGroupByList, FAggList:TStringList;
 public
   constructor Create(ADataset:TClientDataset);
   destructor Destroy;override;
   procedure AddGroupBy(AFields:string);
   procedure AddAggregate(AFieldName:string; AAggType:TAggType);
   function GetGroupingDataset:TClientDataset;
 end;

implementation

{ TGroupBy }

constructor TGroupBy.Create(ADataset: TClientDataset);
begin
 FDataset:=ADataset;
 FGroupByList:=TStringList.Create;
 FAggList:=TStringList.Create;
end;

destructor TGroupBy.Destroy;
begin
 FGroupByList.Free;
 FAggList.Free;
 inherited;
end;

procedure TGroupBy.AddGroupBy(AFields: string);
begin
 FGroupByFields:=AFields;
 FGroupByList.Text:=StringReplace(FGroupByFields,";",#13#10,[rfReplaceAll]);
end;

procedure TGroupBy.AddAggregate(AFieldName: string; AAggType: TAggType);
begin
 FAggList.AddObject(AFieldName, Pointer(AAggType));
end;

function TGroupBy.GetGroupingDataset: TClientDataset;

 procedure SortDataset(ADataset:TClientDataset);
 var
   idxDef:TIndexDef;
 begin
   idxDef:=ADataset.IndexDefs.AddIndexDef;
   idxDef.Name:="SortIndex";
   idxDef.Fields:=FGroupByFields;
   idxDef.Options:=[];
   ADataset.IndexName:=idxDef.Name;
 end;

 function CreateGroupingDataset(AFromDataset:TClientDataset):TClientDataset;

   procedure AddFields(ADataset:TClientDataset; AFieldList:TStringList);
   var
     i:integer;
     newField,oldField:TField;
   begin
     for i:=0 to AFieldList.Count-1 do
     begin
       oldField:=AFromDataset.FieldByName(AFieldList[i]);
       newField:=TFieldClass(oldField.ClassType).Create(ADataset);
       newField.Size:=oldField.Size;
       newField.FieldName:=oldField.FieldName;
       newField.DataSet:=ADataset;
     end;
   end;

 begin
   Result:=TClientDataset.Create(nil);
   AddFields(Result,FGroupByList);
   AddFields(Result,FAggList);
   Result.CreateDataSet;
 end;

 procedure CopyToArray(ADataset:TDataset; var AArr:Variant);
 var
   i:integer;
 begin
   for i:=VarArrayLowBound(AArr,1) to VarArrayHighBound(AArr,1) do
     AArr[i]:=ADataset.Fields[i].Value;
 end;

 procedure ZeroArray(var AArr:Variant);
 var
   i:integer;
 begin
   for i:=VarArrayLowBound(AArr,1) to VarArrayHighBound(AArr,1) do
     AArr[i]:=0;
 end;

 procedure UpdateArray(ADataset:TDataset; var AArr:Variant);
 var
   i:integer;
 begin
   for i:=VarArrayLowBound(AArr,1) to VarArrayHighBound(AArr,1) do
     AArr[i]:=AArr[i]+ADataset.Fields[i+FGroupByList.Count].Value;
 end;

 function NeedChange(ADataset:TDataset; var AArr:Variant):boolean;
 var
   i:integer;
 begin
   Result:=false;
   for i:=VarArrayLowBound(AArr,1) to VarArrayHighBound(AArr,1) do
     if AArr[i]<>ADataset.Fields[i].Value then
     begin
       Result:=true;
       break;
     end;
 end;

 procedure PostData(ADataset:TDataset; var AArr:Variant; var AAgg:Variant);
 var
   i:integer;
 begin
   ADataset.Insert;
   for i:=VarArrayLowBound(AArr,1) to VarArrayHighBound(AArr,1) do
     ADataset.Fields[i].Value:=AArr[i];
   for i:=VarArrayLowBound(AAgg,1) to VarArrayHighBound(AAgg,1) do
     ADataset.Fields[i+FGroupByList.Count].Value:=AAgg[i];
   ADataset.Post;
 end;

var
 Arr,Agg:Variant;
 FCloneDataset:TClientDataset;
begin
 FCloneDataset:=CreateGroupingDataset(FDataset);
 try
   FCloneDataset.XMLData:=FDataset.XMLData;
   SortDataset(FCloneDataset);
   Result:=CreateGroupingDataset(FCloneDataset);
   FCloneDataset.First;
   Arr:=VarArrayCreate([0,FGroupByList.Count-1],varVariant);
   CopyToArray(FCloneDataset,Arr);
   Agg:=VarArrayCreate([0,FAggList.Count-1],varVariant);
   ZeroArray(Agg);
   while not FCloneDataset.Eof do
   begin
     if NeedChange(FCloneDataset,Arr) then
     begin
       PostData(Result,Arr,Agg);
       CopyToArray(FCloneDataset,Arr);
       ZeroArray(Agg);
     end;
     UpdateArray(FCloneDataset,Agg);
     FCloneDataset.Next;
   end;
   PostData(Result,Arr,Agg);
 finally
   FCloneDataset.Free;
 end;
end;

end.


 
Polevi ©   (2005-05-13 09:19) [7]

модуль недоделан, в данном варианте работает только SUM с группировкой по одному полю, но тебе вреде этого будет достаточно, если я правильно понял

пример

 gb:=TGroupBy.Create(someClientDataset);
 gb.AddGroupBy("id_balance_org");
 gb.AddAggregate("sum_1",atSum);
 gb.AddAggregate("sum_2",atSum);
 grpDataset:=gb.GetGroupingDataset;


 
Lexer ©   (2005-05-13 16:34) [8]

Polevi: да, одного Sum достаточно, но я уже сделал несколько кверей и назло заказчику модуль работает так что он может идти курить нажав кнопку refresh ))
за код огромное спасибо, посмотрю как-нить и думаю всё-таки переделаю по твоему



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

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

Наверх




Память: 0.49 MB
Время: 0.025 c
14-1117214164
Alexander Panov
2005-05-27 21:16
2005.06.29
Слов нет. Кто-то глючит.


3-1116588216
dream
2005-05-20 15:23
2005.06.29
Ошибка при добавлени записи в базу


1-1117866831
аматор
2005-06-04 10:33
2005.06.29
редактор


14-1117653659
Aldor
2005-06-01 23:20
2005.06.29
Фотографии со спутника


3-1113979898
pavel_guzhanov
2005-04-20 10:51
2005.06.29
SQLQuery и MySQL