5

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

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

+0

Какой тип набора данных вы используете? – Linas

+0

@Linas TAdsQuery –

+0

Рассчитана колонка, которую вы хотите использовать для заказа? (с использованием OnCalcFields) – Cesar

ответ

2

Существует вероятность того, что разделяет сходство с ответом Йенса (+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 поле в таблице темп, чтобы содержать нужный порядок (это может быть любой тип данных сортируемых - не должен быть целым числом):

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; 
+0

+1 Это хорошая идея, если у вас есть уникальный ключ, который вы можете использовать. –

+0

Мне нравится это больше всего для больших наборов данных, потому что количество данных для передачи кажется наименее. Для небольших наборов данных я бы, вероятно, пошел на один из CDS-решений. –

2

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

я бы:

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

Это на стороне сервера, вы можете, конечно, изменить порядок на стороне клиента, как и некоторые другие ответы. –

+0

+1 Мне нравится идея, потому что я не хочу сразу передавать все данные на CDS. Ответ Марка идет еще дальше, не копируя все данные в временную таблицу. –

3

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

here Как подключить clientdataset к другому набору данных в том же приложении.

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

Хорошая идея, но это скопирует все мои данные на CDS. Таким образом, это вариант для небольших наборов данных. –

1

Основной трюк здесь будет использовать внутреннее известково поле (FieldKind = fkInternalCalc), если они поддерживаются вашим TDataset подкласс. Если это не так, используйте TClientDataset в качестве промежуточного.

DFM:

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

па:

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; 

 Смежные вопросы

  • Нет связанных вопросов^_^