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

如何快速篩選出2個Table,內重覆的資料[交集查詢]

答題得分者是:senso
shchen
一般會員


發表:12
回覆:26
積分:7
註冊:2003-08-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-07-15 21:56:37 IP:202.173.xxx.xxx 訂閱
我有2個Table,其資料的結構完全相同,我查買了MSSQL書籍內有說,INTERSECT 交集查詢即可篩選出兩組資料表共同的記錄,如下SQL指令,
Query1->Close();
Query1->SQL->Clear();
Query1->SQL->Add("SELECT * FROM Table1.db");
Query1->SQL->Add("INTERSECT");
Query1->SQL->Add("SELECT * FROM Table2.db");
Query1->Open();

我執行後會產生,下述錯誤訊息
Invalid use of keyowrd.
Token: SELECT
Line Number:3

而若我將INTERSECT 改為UNION,就完全沒問題,但UNION只是會讓重覆的記錄顯示一次,無法達到我要的功能,是Query1沒有INTERSECT 指令嗎?而我在MSDN上也看到了EXCEPT 的指令,執行結果也是如上的相同錯誤,原因是為什麼?是這兩個指令是MSSQL 才用的指令嗎?
若真是如此,那要怎樣的程式碼,才能使用TQuery 元件,達到交集查詢的功能
http://msdn.microsoft.com/zh-tw/library/ms191255.aspx

senso
高階會員


發表:5
回覆:126
積分:226
註冊:2003-11-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-07-16 09:35:03 IP:61.219.xxx.xxx 訂閱
SQL Server 2000 不支援EXCEPT 和 INTERSECT
SQL Server 2005才有支援

請改用NOT EXIST和EXIST
shchen
一般會員


發表:12
回覆:26
積分:7
註冊:2003-08-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-07-16 11:02:38 IP:202.173.xxx.xxx 訂閱
不好意思,我沒有說明我的資料庫table是Paradox,我是利用TQuery 元件透過DBE來操作,我並沒有使用SQL Server 2000或2005,我只是在local Table 內操作即可,請問方法有解嗎?若要換資料庫也可以,因為我的資料記錄不大,可以重建,但要更換哪個DBE 內附的資料庫呢?

我主要的Function,是我有一個資料表,在收集網卡的MAC ID,當我有2000個新收集到的MAC ID要記錄到資料表內時,我要先判斷這些ID是否已存在資料庫內,而原本我是使用for 迴圈配合Table1->Locate();的方式一一比對有沒有存在,但效率太差了,在當我的資料表內已有30000個ID時,用迴圈判斷1000個新ID有沒有存在資料表內,就需花上4分鐘的時間.太久了.

我改成以下NOT EXIST 程EXIST 也是不行也
Query1->SQL->Add("SELECT * FROM Table1.db EXIST SELECT * FROM Table2.db"); -->顯示Invalid use of keyword. Token: SELECT
Query1->SQL->Add("SELECT * FROM Table1.db NOT EXIST SELECT * FROM Table2.db"); -->顯示Invalid use of keyword. Token: NOT
是我用錯了嗎?還是TQuery 也沒有這兩個指令?

===================引 用 senso 文 章===================
SQLServer2000 不支援EXCEPT 和 INTERSECT
SQLServer2005才有支援

請改用NOT EXIST和EXIST
senso
高階會員


發表:5
回覆:126
積分:226
註冊:2003-11-27

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-07-16 11:50:38 IP:61.219.xxx.xxx 訂閱
Paradox我沒用過
Table1->Locate();查1000次有要這麼久嗎@@?
直接用sql查呢? select * from table where id='xxxx'


可能各種資料庫會略有不同,通常EXIST寫法應該是
select * from table1 as t1 where exists (select * from table2 as t2 where t1.pk=t2.pk)
也可以寫inner join當作交集

差集的話
select * from table1 as t1 where not exists (select * from table2 as t2 where t1.pk=t2.pk)
union all
select * from table2 as t2 where not exists (select * from table1 as t1 where t2.pk=t1.pk)



編輯記錄
senso 重新編輯於 2010-07-16 11:58:55, 註解 無‧
shchen
一般會員


發表:12
回覆:26
積分:7
註冊:2003-08-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-07-16 17:24:34 IP:202.173.xxx.xxx 訂閱
感謝senso 的解說,交集查詢可以用了,若有需要的人可參考,我的指令如下:

Query1->Close();
Query1->SQL->Clear();
Query1->SQL->Add("SELECT * FROM Table1.db as t1 WHERE EXISTS (SELECT * FROM Table2.db as t2 WHERE t1.MAC=t2.MAC)");
Query1->Open();
以上查詢效率,在40000筆記錄中查詢1000筆新資料是否有存在,需花65秒.

以do while 迴圈 WHERE MAC = " "方式
Query1->Close();
Query1->SQL->Clear();
Query1->SQL->Add("SELECT MAC FROM Table1.db WHERE MAC ='" ValueListEditor1->Keys[i] "'");
Query1->Open();
以上查詢效率,在40000筆記錄中查詢1000筆新資料是否有存在,需花26秒.

以do while 迴圈 Locate= 的方式
Table1->DisableControls();
do{
i ;
success=Table1->Locate("MAC",ValueListEditor1->Values[ValueListEditor1->Keys[i]],SearchOptions);
if(success) return;
} while (iRowCount-1);
Table1->EnableControls();
以上查詢效率,在40000筆記錄中查詢1000筆新資料是否有存在,需花44秒.

看來交集查詢的效率不比SELECT * FROM xxx WHERE xxx=xxx來的快.

補充之前使用Locate 之所以會查很久,是因為忘了加DisableControls(); 導致效率降低,使用迴圈查詢Table的人,記得加上DisableControls()&EnableControls() 喔.

編輯記錄
shchen 重新編輯於 2010-07-16 17:26:38, 註解 無‧
shchen 重新編輯於 2010-07-16 17:34:44, 註解 無‧
shchen
一般會員


發表:12
回覆:26
積分:7
註冊:2003-08-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2010-07-16 20:50:22 IP:202.173.xxx.xxx 訂閱
再次研究我的資料庫查詢效率為何這麼慢,發現以下方式可讓SQL加速處理,原因很簡單,就是以"索引" 來加速資料庫查詢速度.
承上題回覆,若將Table1 的MAC 欄位設為Primery Key
Query1->SQL->Add("SELECT * FROM Table1.db as t1 WHERE EXISTS (SELECT * FROM Table2.db as t2 WHERE t1.MAC=t2.MAC)");相同的交集查詢,在40000筆記錄中查詢1000筆新資料是否有存在,依然65秒.
以do while 迴圈 WHERE MAC = " "相同方式查詢效率,在40000筆記錄中查詢1000筆新資料是否有存在26秒變成4秒.
以do while 迴圈 Locate= 的相同方式查詢效率,在40000筆記錄中查詢1000筆新資料是否有存在,依然是44秒,

而最快的是直接以SQL 指令以MAC欄位建立索引關係,自然處理最快.
Query1->SQL->Add("SELECT * FROM FON_MAC_SN_Export, FON_MAC_SN_Export_temp WHERE FON_MAC_SN_Export.MAC = FON_MAC_SN_Export_temp.MAC"); 在40000筆記錄中查詢1000筆新資料是否有存在,費時<1秒.

系統時間:2017-10-18 7:54:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!