Пользовательский порядок сортировки для набора данных после выполнения запроса? - PullRequest
6 голосов
/ 26 октября 2011

Я хочу, чтобы набор результатов запроса к базе данных имел определенный порядок.Информация, которую я хочу упорядочить, не содержится в базе данных, а динамически генерируется в коде (поэтому я не могу использовать ORDER BY).

Есть ли способ сортировки набора данных после выполнения запроса к базе данных?(Мне не нужен индексированный доступ, но я хочу перебирать все записи.)

Ответы [ 4 ]

3 голосов
/ 27 октября 2011

С ClientDataset вы можете изменить порядок после выполнения. Настройки IndexFieldNames сортирует набор данных.

Вы можете найти информацию здесь , как подключить набор данных клиента к другому набору данных в том же приложении.

  object DataSetProvider1: TDataSetProvider
    DataSet = MyAdsQuery
    Left = 208
    Top = 88
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 296
    Top = 88
  end
2 голосов
/ 27 октября 2011

Основным трюком здесь было бы использование внутреннего поля calc (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;
2 голосов
/ 26 октября 2011

Существует вероятность того, что сходство с ответом Йенса (+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' );

Если вы знаете желаемый короткий ордер (либо путем обработки таблицы, либо с помощью какого-либо результата запроса из нее), создайте временную таблицу с некоторым значением ключачтобы сопоставить нужные строки из исходной таблицы, а затем данные о порядке сортировки:

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

Установите в поле sortvalue во временной таблице требуемый порядок (это может быть любой сортируемый тип данных - hasnне должно быть целым числом):

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; 
2 голосов
/ 26 октября 2011

AFAIK единственный надежный способ сортировки набора данных - это использовать ORDER BY.

Я бы:

  1. Добавить фиктивное поле order_tag к вашему запросу.*
  2. Вывести результаты во временную таблицу.
  3. Объявить курсор для итерации по временной таблице и установить order_tag, используя собственную логику и операторы UPDATE #temp_table.
  4. Выберитеданные из временной таблицы и порядок по полю тега.
...