線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1637
推到 Plurk!
推到 Facebook!

DBGrid有一欄位無法顯示

答題得分者是:folkchen
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-23 19:20:44 IP:61.221.xxx.xxx 未訂閱
Hello, everybody: 我用的是BCB5.0 + MySQL 有兩個資料表, 一個是進貨(Import_TB, 欄位有ID,Goods_ID,QTY); 一個是出貨(Export_TB, 欄位有ID,Goods_ID,QTY). 我要顯示庫存資料在DBGrid上 Query語法如下: Select IT.Goods_ID, (IT.QTY-ET.QTY) as Left_QTY From Import_TB as IT Left Join Export_TB as ET On IT.Goods_ID = ET.Goods_ID Order by IT.Goods_ID    
 
    Query1->Close();
    Query1->SQL->Clear();
    Query1->SQL->Add("Select IT.Goods_ID, (IT.QTY-ET.QTY) as Left_QTY");
    Query1->SQL->Add("From Import_TB as IT Left Join Export_TB as ET");
    Query1->SQL->Add("On IT.Goods_ID = ET.Goods_ID");
    Query1->SQL->Add("Order by IT.Goods_ID");
    if (!Query1->Prepared)
        Query1->Prepare();
    Query1->Open();
DBGrid有兩個欄位, 一個是Goods_ID, 一個是Left_QTY 結果Left_QTY那個Column皆是空白,是String/Integer的關係嗎? 如何解決? 另外, 我要求得庫存量, 不知上面SQL語法是否有誤? 請不否指教, 謝謝!
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-23 20:33:48 IP:221.169.xxx.xxx 未訂閱
furbylin:這用不到Join吧,試試下面紅字部分! Query1->Close(); Query1->SQL->Clear(); Query1->SQL->Add("Select IT.Goods_ID, (IT.QTY-ET.QTY) as Left_QTY"); Query1->SQL->Add("From Import_TB as IT , Export_TB as ET"); Query1->SQL->Add("where IT.Goods_ID = ET.Goods_ID"); Query1->SQL->Add("Order by IT.Goods_ID"); if (!Query1->Prepared) Query1->Prepare(); Query1->Open(); 請參考! Andy Chang
------
Andy Chang
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-24 09:54:52 IP:61.221.xxx.xxx 未訂閱
引言: furbylin:這用不到Join吧,試試下面紅字部分! Query1->Close(); Query1->SQL->Clear(); Query1->SQL->Add("Select IT.Goods_ID, (IT.QTY-ET.QTY) as Left_QTY"); Query1->SQL->Add("From Import_TB as IT , Export_TB as ET"); Query1->SQL->Add("where IT.Goods_ID = ET.Goods_ID"); Query1->SQL->Add("Order by IT.Goods_ID"); if (!Query1->Prepared) Query1->Prepare(); Query1->Open(); 請參考! Andy Chang
您好: 假設我的進貨資料表有下列4筆記錄: 1 1 100 2 3 150 3 2 50 4 5 200 而我出貨資料表是空的. 我希望DBGrid顯示出來的庫存資料如下: 1 100 2 50 3 150 5 200 如果照你說的方法去做, 結果DBGrid內容是空的. 我沒辦法解決的問題主要是Left_QTY那欄無法顯示. 再假設我的出貨資料表有2筆資料, 如下: 1 3 150 2 5 100 結果DBGrid顯示出來的庫存資料如下: 1 100 2 50 3 0 5 100 發表人 - furbylin 於 2004/09/24 10:15:29
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-24 16:12:10 IP:221.169.xxx.xxx 未訂閱
furbylin:知道你要的東西了,因為left join後不存在的數值會變成NULL 請將Import_TB及Export_TB的QTY設成DEFAULT 0;試試看。 紅字部分的Export_TB一定要設。 請參考! Andy Chang
------
Andy Chang
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-24 17:21:28 IP:61.221.xxx.xxx 未訂閱
您好: 您的意思是將Import_TB及Export_TB的QTY欄位設成Default 0嗎? 我已經照您的方法做了, 結果還是一樣, 不知道是不是建立資料表時出了問題. 我是用MySQL Control Center建立資料表的.
andychang1690
資深會員


發表:20
回覆:694
積分:442
註冊:2003-03-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-24 19:17:16 IP:221.169.xxx.xxx 未訂閱
引言: 您好: 您的意思是將Import_TB及Export_TB的QTY欄位設成Default 0嗎? 我已經照您的方法做了, 結果還是一樣, 不知道是不是建立資料表時出了問題. 我是用MySQL Control Center建立資料表的.
furbylin:我沒有MYSQL,但我使用其他SQL測試可以,
CREATE TABLE  Export_TB (
   ID        VARCHAR(20),
   Goods_ID  VARCHAR(30),
   QTY       DECIMAL(8,3) DEFAULT 0
);
我的意思如上!你的QTY 一產生DEFAULT為0
Andy Chang
------
Andy Chang
folkchen
高階會員


發表:9
回覆:232
積分:173
註冊:2003-10-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-29 08:49:27 IP:211.20.xxx.xxx 未訂閱
你是 Join 有缺項的Table,所以還是要用 Left Join 你參考下列SQL試試 Query1->SQL->Add("Select IT.Goods_ID, (sum(IT.QTY)-sum(ET.QTY)) as Left_QTY"); Query1->SQL->Add("From Import_TB as IT Left Join Export_TB as ET"); Query1->SQL->Add("On IT.Goods_ID = ET.Goods_ID"); Query1->SQL->Add("Group by IT.Goods_ID"); Query1->SQL->Add("Order by IT.Goods_ID"); 若不行第一行改用下面的試 Query1->SQL->Add("Select IT.Goods_ID, (if(sum(IT.QTY) is null,0,sum(IT.QTY)) - if(sum(ET.QTY) is null,0,sum(ET.QTY))) as Left_QTY"); 或是把 IF 放進最內層 Query1->SQL->Add("Select IT.Goods_ID, (sum(if(IT.QTY is null,0,IT.QTY)) - sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY"); 你的問題出在 Join 後為 NULL ,但我不知MYSQL有什麼 Function 可以處理NULL的轉換 在Oracle中可以用 NVL(sum(ET.QTY),0) 來將NULL轉成0 Accress 可以用 iif(....) 來轉 可是MYSQL我不熟,你再試看看 發表人 - folkchen 於 2004/09/29 09:16:28
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-29 12:00:34 IP:61.221.xxx.xxx 未訂閱
引言: 你是 Join 有缺項的Table,所以還是要用 Left Join 你參考下列SQL試試 Query1->SQL->Add("Select IT.Goods_ID, (sum(IT.QTY)-sum(ET.QTY)) as Left_QTY"); Query1->SQL->Add("From Import_TB as IT Left Join Export_TB as ET"); Query1->SQL->Add("On IT.Goods_ID = ET.Goods_ID"); Query1->SQL->Add("Group by IT.Goods_ID"); Query1->SQL->Add("Order by IT.Goods_ID"); 若不行第一行改用下面的試 Query1->SQL->Add("Select IT.Goods_ID, (if(sum(IT.QTY) is null,0,sum(IT.QTY)) - if(sum(ET.QTY) is null,0,sum(ET.QTY))) as Left_QTY"); 或是把 IF 放進最內層 Query1->SQL->Add("Select IT.Goods_ID, (sum(if(IT.QTY is null,0,IT.QTY)) - sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY"); 你的問題出在 Join 後為 NULL ,但我不知MYSQL有什麼 Function 可以處理NULL的轉換 在Oracle中可以用 NVL(sum(ET.QTY),0) 來將NULL轉成0 Accress 可以用 iif(....) 來轉 可是MYSQL我不熟,你再試看看 發表人 - folkchen 於 2004/09/29 09:16:28
您好: 抱歉, 這幾天放假, 跑去玩了. 我照您的方法做, DBGrid1上的Left_QTY欄可以顯示出資料了耶! 謝謝您! Query1->SQL->Add("Select IT.Goods_ID, (if(sum(IT.QTY) is null,0,sum(IT.QTY)) - if(sum(ET.QTY) is null,0,sum(ET.QTY))) as Left_QTY"); 或 Query1->SQL->Add("Select IT.Goods_ID, (sum(if(IT.QTY is null,0,IT.QTY)) - sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY"); Query1->SQL->Add("From Import_TB as IT Left Join Export_TB as ET"); Query1->SQL->Add("On IT.Goods_ID = ET.Goods_ID"); Query1->SQL->Add("Group by IT.Goods_ID"); Query1->SQL->Add("Order by IT.Goods_ID"); 得到的答案都一樣. 但是有另外一個問題產生. 假設我的進貨資料表有下列5筆記錄: 1 1 100 2 2 150 3 2 50 4 5 200 5 2 40 而我出貨資料表有1筆記錄: 1 2 20 則DBGrid1顯示出來的資料如下: 1 100 2 180 5 200 第2筆應該是220, 結果卻是180, 得到一個結論:IT 資料表有幾筆就減幾次, 是不是Group By這裡出問題? 另外一個問題: if(sum(IT.QTY) is null,0,sum(IT.QTY)) 第三個參數sum(IT.QTY)代表何意? 我在MySQL中找不到if(...)的語法.
folkchen
高階會員


發表:9
回覆:232
積分:173
註冊:2003-10-09

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-09-29 12:33:12 IP:211.20.xxx.xxx 未訂閱
你試著將2個Sum不要相減,直接看它進貨和出貨各是SUM成什麼值 if(sum(IT.QTY) is null,0,sum(IT.QTY)) 如果sum(IT.QTY) is null成立,就傳回0 否則傳回sum(IT.QTY) 第三個參數sum(IT.QTY)就是不成立時傳回的值
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-09-29 14:40:25 IP:61.221.xxx.xxx 未訂閱
引言: 你試著將2個Sum不要相減,直接看它進貨和出貨各是SUM成什麼值
我用上面的範例, 針對出貨資料表做select. Select ET.Goods_ID, (sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY From Export_TB as ET Group by ET.Goods_ID Order by ET.Goods_ID 得到的結果為: 2 20 若改為 Select ET.Goods_ID, (sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY From Import_TB as IT Left Join Export_TB as ET On IT.Goods_ID = ET.Goods_ID Group by ET.Goods_ID Order by ET.Goods_ID 得到的結果為:
    0
2   60
進貨資料表使用上述兩方法得到的結果都一樣, 如下:
1   100
2   240
5   200
如果把它改成: Select IT.Goods_ID, (sum(if(IT.QTY is null,0,IT.QTY)) - sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY From Import_TB as IT Natural Left Join Export_TB as ET Group by IT.Goods_ID Order by IT.Goods_ID 得到的結果為:
1   100
2   240
5   200
如果把它改成: Select IT.Goods_ID, (sum(if(IT.QTY is null,0,IT.QTY)) - sum(if(ET.QTY is null,0,ET.QTY))) as Left_QTY From Import_TB as IT ,Export_TB as ET Group by IT.Goods_ID Having It.Goods_ID = ET.Goods_ID Order by IT.Goods_ID 卻發生語法錯誤, 不知Having 該如何使用? 頭暈@_@, 繼續努力中...
folkchen
高階會員


發表:9
回覆:232
積分:173
註冊:2003-10-09

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-09-29 16:51:02 IP:211.20.xxx.xxx 未訂閱
我知道了,問題出在 Left Join 會有資料虛增的情況 可以用/count(1)或雙View的方式解決 但剛剛想到一個最大的問題 你的資料會有有時左邊缺項,有時右邊缺項的問題 沒有一個Join可以滿足你的需求 要用特殊技巧才能做出來 MySQL我不熟,可能幫不上忙了 希望有其他大大可以幫的上
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-09-29 17:42:55 IP:61.221.xxx.xxx 未訂閱
引言: 我知道了,問題出在 Left Join 會有資料虛增的情況 可以用/count(1)或雙View的方式解決 但剛剛想到一個最大的問題 你的資料會有有時左邊缺項,有時右邊缺項的問題 沒有一個Join可以滿足你的需求 要用特殊技巧才能做出來 MySQL我不熟,可能幫不上忙了 希望有其他大大可以幫的上
您好: 這個問題, 我用最笨的方法解決, 就是另建一個庫存資料表(Stock_TB), 只要有進貨或出貨就去更新庫存料表, 方法如下:
void __fastcall TForm1::RefreshStock(int nGoodsID)
{
    int nImportQTY, nExportQTY, nLeftQTY;        QueryTmp->Close();
    QueryTmp->SQL->Clear();
    QueryTmp->SQL->Add("Select Goods_ID, SUM(if(Import_QTY is null,0,Import_QTY)) as ImportQTY");
    QueryTmp->SQL->Add("From Import_TB");
    QueryTmp->SQL->Add("Group By Goods_ID");
    QueryTmp->SQL->Add("Having Goods_ID = :ID");
    QueryTmp->ParamByName("ID")->Value = nGoodsID;
    if (!QueryTmp->Prepared)
        QueryTmp->Prepare();
    QueryTmp->Open();
    nImportQTY = QueryTmp->FieldByName("ImportQTY")->AsInteger;        QueryTmp->Close();
    QueryTmp->SQL->Clear();
    QueryTmp->SQL->Add("Select Goods_ID, SUM(if(Export_QTY is null,0,Export_QTY)) as ExportQTY");
    QueryTmp->SQL->Add("From Export_TB");
    QueryTmp->SQL->Add("Group By Goods_ID");
    QueryTmp->SQL->Add("Having Goods_ID = :ID");
    QueryTmp->ParamByName("ID")->Value = nGoodsID;
    if (!QueryTmp->Prepared)
        QueryTmp->Prepare();
    QueryTmp->Open();
    nExportQTY = QueryTmp->FieldByName("ExportQTY")->AsInteger;        nLeftQTY = nImportQTY - nExportQTY;        QueryTmp->Close();
    QueryTmp->SQL->Clear();
    QueryTmp->SQL->Add("Select * From Stock_TB");
    QueryTmp->SQL->Add("Where Goods_ID = :ID");
    QueryTmp->ParamByName("ID")->Value = nGoodsID;
    if (!QueryTmp->Prepared)
        QueryTmp->Prepare();
    QueryTmp->Open();        // 庫存資料表裡面有此記錄
    if (QueryTmp->RecordCount > 0)
    {
        if (nLeftQTY <= 0)  //刪除此記錄
        {
            QueryTmp->Close();
            QueryTmp->SQL->Clear();
            QueryTmp->SQL->Add("Delete from Stock_TB");
            QueryTmp->SQL->Add("Where Goods_ID = :GoodsID");
            QueryTmp->ParamByName("GoodsID")->AsInteger = nGoodsID;
            if (!QueryTmp->Prepared)
                QueryTmp->Prepare();
            QueryTmp->ExecSQL();
        }
        else    // 更新此記錄
        {
            QueryTmp->Close();
            QueryTmp->SQL->Clear();
            QueryTmp->SQL->Add("Update Stock_TB");
            QueryTmp->SQL->Add("Set Left_QTY=:LeftQTY");
            QueryTmp->SQL->Add("Where Goods_ID=:ID");
            QueryTmp->ParamByName("ID")->AsInteger = nGoodsID;
            QueryTmp->ParamByName("LeftQTY")->AsInteger = nLeftQTY;
            if (!QueryTmp->Prepared)
                 QueryTmp->Prepare();
            QueryTmp->ExecSQL();
        }
    }
    else
    {
        QueryTmp->Close();
        QueryTmp->SQL->Clear();
        QueryTmp->SQL->Add("Insert Into Stock_TB(Goods_ID, Left_QTY)");
        QueryTmp->SQL->Add("Values (:GoodsID, :LeftQTY)");
        QueryTmp->ParamByName("GoodsID")->AsInteger = nGoodsID;
        QueryTmp->ParamByName("LeftQTY")->AsInteger = nLeftQTY;
        if (!QueryTmp->Prepared)
            QueryTmp->Prepare();
        QueryTmp->ExecSQL();
    }
}     
我在想是不是我的資料表沒有經過正規化, 才會造成這種現象. 至於您說的"/count(1)"或"雙View"的方式是什麼, 我不清楚, 我到想見識見識. 多謝您的幫忙, 讓我知道整數還有NULL的問題. 也請各位先進若有更好的方法請不否告知, 謝謝!
folkchen
高階會員


發表:9
回覆:232
積分:173
註冊:2003-10-09

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-09-30 08:37:05 IP:211.20.xxx.xxx 未訂閱
假設我的進貨資料表有下列5筆記錄: 1 1 100 2 2 150 3 2 50 4 5 200 5 2 40 而我出貨資料表有1筆記錄: 1 2 20 在Left Join時2的資料會變成 2 150 20 2 50 20 2 40 20 Sum就會變成 150 50 40 20 20 20 所以若知道後面的是虛增,就可以/Count(1) (count計算資料筆數,()中的1沒有意義你要用*也可以) 150 50 40 (20 20 20)/3 就會正確了 雙View 就是對2個TABLE依ID做Sum(Qty)的 VIEW,再來對VIEW做JOIN,就不會有虛增的筆數了 View 的內容: select id,sum(qty) from xxx 這兩個方法只能解決JOIN時筆數虛增的問題 >我在想是不是我的資料表沒有經過正規化, 才會造成這種現象. 算是吧 若你有建ID檔此題就有解了,用雙VIEW的方式 2個TABLE先對ID檔Left Join(做成View),再互相Join 但ID檔中所有的ID都會被列出 除非你再去剔除進出數量都是0的,才會只出現有進出的資料 P.S:若MYSQL有支援SubQuery就可以用一個SQL寫好,不用做成雙VIEW
furbylin
一般會員


發表:6
回覆:29
積分:12
註冊:2003-08-29

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-09-30 10:45:41 IP:61.221.xxx.xxx 未訂閱
亂了! 亂了!
假設我的進貨資料表有下列5筆記錄:
1   1   100
2   2   150
3   2   50
4   5   200
5   2   40    而我出貨資料表有2筆記錄:
1   2   20
2   2   30    經過SQL之後, 得到的結果變成:
1   100
2   390
5   200     
390怎麼來的, 搞不懂, 所以用/Count(*)是不可行的 看樣子只有改變資料表設計了, 謝謝您, 辛苦了!
系統時間:2024-05-05 23:41:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!