DBGrid有一欄位無法顯示 |
答題得分者是:folkchen
|
furbylin
一般會員 發表:6 回覆:29 積分:12 註冊:2003-08-29 發送簡訊給我 |
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 發送簡訊給我 |
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 發送簡訊給我 |
引言: 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 發送簡訊給我 |
|
furbylin
一般會員 發表:6 回覆:29 積分:12 註冊:2003-08-29 發送簡訊給我 |
|
andychang1690
資深會員 發表:20 回覆:694 積分:442 註冊:2003-03-14 發送簡訊給我 |
引言: 您好: 您的意思是將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為0Andy Chang
------
Andy Chang |
folkchen
高階會員 發表:9 回覆:232 積分:173 註冊:2003-10-09 發送簡訊給我 |
你是 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 發送簡訊給我 |
引言: 你是 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 發送簡訊給我 |
|
furbylin
一般會員 發表:6 回覆:29 積分:12 註冊:2003-08-29 發送簡訊給我 |
引言: 你試著將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 發送簡訊給我 |
|
furbylin
一般會員 發表:6 回覆:29 積分:12 註冊:2003-08-29 發送簡訊給我 |
引言: 我知道了,問題出在 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 發送簡訊給我 |
假設我的進貨資料表有下列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 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |