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); 

는 그런 다음 정렬 순서를 제공하는 테이블에 대해 조인과 결과를 생성 : 당신이 실행 한 후 순서를 변경할 수됩니다 ClientDataset의와

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. 커서를 선언하여 임시 테이블을 반복하고 사용자 지정 논리와 UPDATE #temp_table 문을 사용하여 order_tag을 설정하십시오.
  4. 임시 테이블에서 데이터를 선택하고 태그 필드로 정렬하십시오.
+0

그것은 서버 측에 있습니다. 물론 클라이언트 측에서 순서를 재지 정할 수도 있습니다. 다른 답변과 비슷합니다. –

+0

+1 모든 데이터를 한 번에 CDS로 전송하고 싶지 않기 때문에이 아이디어가 마음에 들었습니다. Mark의 답변은 모든 데이터를 임시 테이블에 복사하지 않아 한 걸음 더 나아갑니다. –

3

합니다. 설정 IndexFieldNames는 데이터 집합을 정렬합니다.

here 같은 응용 프로그램에서 클라이언트 데이터 집합을 다른 데이터 집합에 연결하는 방법을 찾을 수 있습니다.

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

주요 트릭은 여기에 그들이 당신의 TDataSet의 하위 클래스에서 지원하는 경우 내부 CALC 필드 (FieldKind = fkInternalCalc)를 사용하는 것입니다. 그렇지 않은 경우 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;