执行查询后数据集的自定义排序顺序?

时间:2011-10-26 13:14:01

标签: delphi sorting dataset delphi-2009 advantage-database-server

我希望数据库查询的结果集具有特定顺序。我想要订购的信息不包含在数据库中,而是在代码中动态生成(因此我不能使用ORDER BY)。

在执行数据库查询后,有没有办法对数据集进行排序? (我不需要索引访问,但只想迭代所有记录。)

4 个答案:

答案 0 :(得分:3)

使用ClientDataset,您可以在执行后更改订单。 设置IndexFieldNames对数据集进行排序。

您可以找到有关如何将clientdataset连接到同一应用程序中的其他数据集的信息here

  object DataSetProvider1: TDataSetProvider
    DataSet = MyAdsQuery
    Left = 208
    Top = 88
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 296
    Top = 88
  end

答案 1 :(得分:2)

AFAIK是对数据集进行排序的唯一可靠方法是使用ORDER BY

我会:

  1. 在您的查询中添加虚拟order_tag字段。
  2. 将结果转储到临时表。
  3. 声明游标迭代临时表并使用您的自定义逻辑和order_tag语句设置UPDATE #temp_table
  4. 从临时表中选择数据,并按标记字段排序。

答案 2 :(得分:2)

有可能与Jens的答案(+1)有相似之处,但结果却略有不同。

给定现有表格:

create table somedata (id integer, name char(20));
insert into somedata values ( 1, 'Tim' );
insert into somedata values ( 2, 'Bob' );
insert into somedata values ( 3, 'Joe' );

如果您知道所需的短订单(通过处理表或其中的某些查询结果),请创建一个临时表,该表具有一些键值以匹配原始表中的所需行,然后是排序顺序数据:< / p>

create table #sortorder( id integer, sortvalue integer );

在临时表中设置sortvalue字段以包含所需的顺序(它可以是任何可排序的数据类型 - 不必是整数):

insert into #sortorder values ( 1, 15 );
insert into #sortorder values ( 2, 12 );
insert into #sortorder values ( 3, 5 );

然后使用针对提供排序顺序的表的连接生成结果:

select sd.* from somedata sd, #sortorder so 
         where sd.id = so.id
         order by so.sortvalue; 

答案 3 :(得分:2)

这里的主要技巧是使用内部计算字段(FieldKind = fkInternalCalc),如果它们受到TDataset子类的支持。如果不是,请使用TClientDataset作为中间体。

DFM:

object ClientDataSet1SortField: TIntegerField
  FieldKind = fkInternalCalc
  FieldName = 'SortField'
end

PAS:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ADOConnection1.Open('dbuser', 'Hunter2');
  ClientDataSet1.SetProvider(ADOQuery1);  // set ClientDataset provider. This will create a TLocalAppServer provider "in the background"
  ClientDataSet1.Open;
  randomize;
  while not ClientDataSet1.Eof do
  begin
    ClientDataSet1.edit;

    ClientDataSet1SortField.AsInteger := random(100);
    // as ClientDataSet1SortField is fkInternalCalc it doesn't need to be in the query result set, but can be assigned and used for sorting
    ClientDataSet1.Post;
    ClientDataSet1.Next;
  end;
  clientdataset1.IndexFieldNames := 'SortField';
end;