Форум: "Базы";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизАгрегирование в 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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.07 c