2010-12-03 70 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