2010-12-03 65 views
1

我不是SQL專家,這是我對錶「查詢」(鍵:SystemId,TopicId,DocumentId,所有也是外鍵)我的SQLite查詢獲取外鍵和插入避免重複。但它是巨大的,醜陋的,我要執行它上千次:如何優化這個龐大而醜陋的查詢,忽略重複?

command.CommandText = "INSERT INTO Query (SystemId, TopicId, DocumentId) " + 
    "(SELECT Id FROM System WHERE Tag = @SystemTag COLLATE NOCASE), " + 
    "(SELECT Id FROM Topic WHERE Number = @TopicNumber COLLATE NOCASE), " + 
    "(SELECT Id FROM Document WHERE Number = @DocNumber COLLATE NOCASE) " + 
    "WHERE NOT EXISTS (SELECT 1 FROM Query WHERE " + 
    "SystemId = (SELECT Id FROM System WHERE Tag = @SystemTag) AND " + 
    "TopicId = (SELECT 1 FROM Topic WHERE Number = @TopicNumber) AND " + 
    "DocumentId = (SELECT Id FROM Document WHERE Number = @DocNumber))"; 

問題:沒有辦法告訴SQL「不用擔心重複,忽略INSERT語句」。或者可能使用變量/臨時表,AD語句?

編輯:直查詢:

INSERT INTO Query (SystemId, TopicId, DocumentId) 
    (SELECT Id FROM System WHERE Tag = @SystemTag COLLATE NOCASE), 
    (SELECT Id FROM Topic WHERE Number = @TopicNumber COLLATE NOCASE), 
    (SELECT Id FROM Document WHERE Number = @DocNumber COLLATE NOCASE) 
    WHERE NOT EXISTS (SELECT 1 FROM Query WHERE 
    SystemId = (SELECT Id FROM System WHERE Tag = @SystemTag) AND 
    TopicId = (SELECT 1 FROM Topic WHERE Number = @TopicNumber) AND 
    DocumentId = (SELECT Id FROM Document WHERE Number = @DocNumber)); 

回答

1

爲了防止插入重複的,你需要兩樣東西:

標識欄爲需要獨特的表定義。例如:

CREATE TABLE Query (
SystemId INTEGER, 
TopicId INTEGER, 
DocumentId INTEGER, 
PRIMARY KEY (SystemId, TopicId, DocumentId)); 

CREATE TABLE Query (
SystemId INTEGER, 
TopicId INTEGER, 
DocumentId INTEGER, 
PRIMARY KEY (SystemId, TopicId, DocumentId)); 

並有conflict clause。爲此,您可以通過以下兩種方式之一,無論是在你的表定義(離開它像上面將使缺省設置忽略,這是相當多的,你想要什麼),或在您的INSERT命令:

INSERT OR IGNORE INTO Query... 

如果你有你的表設置與UNIQUE約束,你真的不需要改變你的INSERT查詢(除了刪除公認醜陋的WHERE NOT EXISTS

缺點是,它使你的代碼嘗試各種插入和失敗,但以另一種方式來看待它:它使你的數據庫按照你希望的方式運行,這對於使用數據庫非常關鍵,你不需要在你所有的時候對所有表進行全面的手動掃描'回覆做手術。你想讓數據庫做骯髒的工作。

0

在你約忽略重複的問題,您需要調查DISTINCT

+0

這在使用SELECT的INSERT中,我需要避免重複... – gremo 2010-12-03 10:05:18

0

我不知道你是怎麼在SQL精簡版做到這一點(如果有任何特定於平臺的語法問題),但刪除重複項的常見方式是使用GROUP BY。

W3Schools的有通用SQL一個很好的例子:

http://www.w3schools.com/sql/sql_groupby.asp

另一種選擇是DISTINCT,但可以在大型數據集的問題。

最後,作爲一種觀察,您可能想要考慮使用JOIN而不是嵌套SELECT。

http://www.w3schools.com/sql/sql_join.asp

+0

INSERT WHERE NOT EXISTS,why GROUP BY should be relevant? – gremo 2010-12-03 10:06:01