全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1827
推到 Plurk!
推到 Facebook!

有關Group By的問題

答題得分者是:sanhang
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-20 00:33:27 IP:61.226.xxx.xxx 未訂閱
select b.custno,a.company,b.shipVia,sum(amountpaid) from customer a, orders b where b.custno=a.custno group by b.custno,a.company,b.shipvia order by b.custno 以上是在TQuery上直接下SQL 指令 請問是否可用TTable直接作出Group by(也就是不要下SQL指令) 可獲得上述的結果,TClientDataSet是否也可以做到?
yachanga
資深會員


發表:24
回覆:335
積分:296
註冊:2003-09-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-20 00:42:32 IP:61.230.xxx.xxx 未訂閱
Hi johnny2212您好: TTable 小弟沒用過 不過TClientDataSet 可以做得到 以下有一個示範教學 參考Justmade板大的範例 -- 不用寫程式碼動態計算總金額 http://delphi.ktop.com.tw/topic.php?topic_id=28513    ~悠遊法國號~
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-06-21 00:52:36 IP:61.226.xxx.xxx 未訂閱
我不是要加總一個欄位(brifecase),我是要做Group by,group by 不會做成全部的sum,他會作成不同群組的Sum
ccchen
版主


發表:61
回覆:940
積分:1394
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-06-21 10:51:57 IP:218.170.xxx.xxx 未訂閱
引言: 我不是要加總一個欄位(brifecase),我是要做Group by,group by 不會做成全部的sum,他會作成不同群組的Sum
去看看TClientDataSet的 aggregates吧
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-06-22 00:46:54 IP:61.226.xxx.xxx 未訂閱
對不起,我前面寫錯了,不是Briefcase,是Aggreate. Aggregate是針對某一個欄位做加總,它是虛擬的,不是從資料庫選取出來的; 我的問題如下 select b.custno,a.company,b.shipVia,sum(amountpaid) as FieldName from customer a, orders b where b.custno=a.custno group by b.custno,a.company,b.shipvia order by b.custno 而 此處的sum(amountpaid) as FieldName 它是一個真正的field,我要的是類似這樣的結果 1221 Chodi UPS 12300 //1221 所有UPS的總合 12300 1223 FDIRE SHE 23456 //1223 所有SHE的總合 23456 1223 FDIRE UPS 1456 //1223 所有UPS的總合 1456 1223 FDIRE GHT 34567 //1223 所有GHT的總合 34567 我這樣說的應該很清楚了吧
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-06-22 01:27:16 IP:203.204.xxx.xxx 未訂閱
引言: 請問是否可用TTable直接作出Group by(也就是不要下SQL指令) 可獲得上述的結果,TClientDataSet是否也可以做到?
johnny2212 你好 TTable無法達到此功能,而TCLientDataSet可以做到(它也是用COmmandText透過DataSetProvider再交給TQuery等元件來產生結果),若不要用下SQL的方式也可以,但可能會寫更多的程式碼,它無法設定幾個屬性值後就可以達成的。 ps:我是很好奇,你的目的只是要產生Group 後的加總而已嗎? 它應該只是初步的統計結果,後續還會利用它作進一步的運算吧!因為TQuery產生Group的統計結果後,卻無法做後續的運算,所以才會尋求其他可以作後續運算的資料集元件,若真是如此,那麼使用TClientDataSet就對啦!
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-06-23 06:16:04 IP:61.226.xxx.xxx 未訂閱
我為何會這樣做?因為我的Database 是分散的,若不用DataSet做Group by的話會非常麻煩,不然就要 Join兩個DataBase(ADO好像還不行),不然就要用OLAP做成需要的格式,這樣又會多出財力負擔,不見得公司會接受 請問Chance36,用TClientDataSet,在不下SQL的條件下,要如何才能達成Group by的效果,能否給一些提示?
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-06-25 00:06:20 IP:203.204.xxx.xxx 未訂閱
johnny2212 你好
先建兩組TQuery->TDataSetProvider->TClientDataSet,設定TDataSetProvider.Options   poAllowCommandText    假設兩個資料庫A及B,第一組連到A,第二組連到B資料庫    CDS1.CommandText := 'select b.custno,a.company,b.shipVia,sum(amountpaid) from customer a, orders b'
                    ' where b.custno=a.custno'
                    ' group by b.custno,a.company,b.shipvia'
                    ' order by b.custno,a.company,b.shipvia';
CDS2.CommandText := 同上 ; // 假設表格名稱及欄位名稱皆同    以CDS1為基本,將CDS2的資料加總到CDS1中      With CDS1 Do Begin
    IndexFieldNames := 'custno;company;shipvia' ; // 先建立索引
    CDS2.First ;
    While Not CDS2.Eof Do Begin
      SetKey;
      FieldByName('custno').AsString := CDS2.FieldByName('custno').AsString;
      FieldByName('company').AsString := CDS2.FieldByName('company').AsString;
      FieldByName('shipvia').AsString := CDS2.FieldByName('shipvia').AsString;
      If Not GotoKey Then Begin
        Append;
        FieldByName('custno').AsString := CDS2.FieldByName('custno').AsString;
        FieldByName('company').AsString := CDS2.FieldByName('company').AsString;
        FieldByName('shipvia').AsString := CDS2.FieldByName('shipvia').AsString;
      End Else Begin
        Edit;
      End;
      FieldByName('amountpaid').AsString := FieldByName('amountpaid').AsString 
                                            CDS2.FieldByName('amountpaid').AsString;
      CDS2.Next;
    End;
  End;    跑完後CDS1的內容即是加總後的結果
sanhang
一般會員


發表:12
回覆:25
積分:17
註冊:2002-08-31

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-06-26 03:16:47 IP:211.74.xxx.xxx 未訂閱
提供另一個方法 如果你的DB是ORACLE 可以用DB-Link的方式Join兩個Table並放在一個View裡提供給App 如果是MS SQL Server的話可以用Linked Server的方式(sp_addlinkedserver)
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-06-26 17:03:38 IP:218.32.xxx.xxx 未訂閱
johnny2212 你好: 試了一下 ClientDataSet AggregateField... 參考看看 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=52324
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-06-26 23:52:00 IP:61.226.xxx.xxx 未訂閱
sanhang,sp_addlinkedserver 要怎麼下,能否告知? Chance36,我的問題就在於 customer, orders 這兩個Table就是在不同的 Database啊,若是能直接能下SQL的話,我何必這麼麻煩?
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-06-27 01:35:14 IP:203.204.xxx.xxx 未訂閱
johnny2212 你好     原來是customer 與orders 分屬不同資料庫,而不是每個資料庫各有一組customer 與 orders ,至於跨資料庫的SQL查詢,應該是可以的,只要你登入的權限夠大,只昃語法我也不熟,我一般的作法還是靠自已來處理特殊的需求,免得受限於不同資料庫的不同語法。 以下提供你自行處理的程式片段
1.建立結果ClientDataSet的欄位結構
  With cds Do Begin
    Close;
    // 以下為Group By  的欄位
    FieldDefs.Add('Custno',ftString,10,False);  // 欄位寬度自訂
    FieldDefs.Add('Company',ftString,20,False);
    FieldDefs.Add('ShipVia',ftString,10,False);
    // 以下為Sum 的欄位
    FieldDefs.Add('AmountPaid'   ,ftFloat, 0,False);
    CreateDataSet; //建立記憶體資料表
    Logchanges := False; // 對於不會更新資料庫的ClientDataSet最好設為False,效率比較好。
  End;    2.開啟相關資料表
  // 開啟主檔
  Query1.DataBaseName := 'A'; // 連到A資料庫
  Query1.SQL.Text := 'Select custno,company From Custon';
  Query1.Open;
  DataSource1.DataSet := Query1;
  // 開啟訂單檔
  Query2.DataBaseName := 'B'; // 連到B資料庫
  Query2.SQL.Text := 'Select custno,shipVia,amountpaid From Orders';
  Query2.Open;
  // 建立關聯
  Query2.MasterSource := DataSource1;
  Query2.MasterField := 'Custno';    3.開啟自行處理Grouop By
  // 建立Group 用的索引
  CDS.IndexFieldNames := 'Custno;Company;ShipVia' ;
  Query1.First;
  While Not Query1.EOf Do Begin
    Query2.First;
    While Not Query2.Eof Do Begin
      // CDS有建索引,故使用locate也無妨
      If Not CDS.locate('Custno,Company,ShipVia'
            ,VarArrayOf([Query2.FieldByName('Custno').AsString
                        ,Query1.FieldByName('Company').AsString
                        ,Query2.FieldByName('ShipVai').AsString])
            ,[]) Then Begin
        CDS.Append; //找不到則用新增的方式,並同時寫入Group的欄位值
        CDS.FieldByName('Custno').AsString := Query2.FieldByName('Custno').AsString;
        CDS.FieldByName('Company').AsString := Query1.FieldByName('Company').AsString;
        CDS.FieldByName('Custno').AsString := Query2.FieldByName('ShipVai').AsString;
      End Else Begin
        CDS.Edit; //找到則用修改的
      End;
      // 自行合計
      CDS.FieldByName('amountpaid').AsFloat := CDS.FieldByName('amountpaid').AsFloat
                                               Query2.FieldByName('Amountpaid').AsString;
      CDS.Post;
      Query2.Next;
    End;
    Query1.Next;
  End;    以上程式看看合不合用!不要看程式好像滿囉唆的,但執行的效率並不差喔!
johnny2212
初階會員


發表:34
回覆:65
積分:39
註冊:2003-04-09

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-06-28 08:58:18 IP:61.226.xxx.xxx 未訂閱
chance36 謝謝您,不過這樣還是太麻煩了,我決定換另一種方法
系統時間:2024-09-17 14:31:00
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!