2010-12-03 8 views
1

Je ne suis pas un expert SQL, voici ma requête SQLite sur la table "Requête" (clé: SystemId, TopicId, DocumentId, toutes aussi des clés étrangères) qui obtient les clés étrangères et les insert en évitant les doublons. Mais il est énorme, laide et je dois exécuter des milliers de fois:Comment optimiser cette requête énorme et laide, en ignorant les doublons?

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))"; 

Question: Toute façon de dire sql « ne vous inquiétez pas de doublons, ignorer l'instruction d'insertion ». Ou peut-être en utilisant des variables/tables temporaires, des déclarations AD?

EDIT: requête droite:

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)); 

Répondre

1

Pour éviter l'insertion d'un double, vous avez besoin de deux choses:

Une définition de table qui identifie les colonnes comme ayant besoin d'être unique. Par exemple:

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

ou

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

Et conflict clause. Vous pouvez le faire de deux façons, soit dans votre définition de la table (en laissant LIKE ci-dessus faire défaut à IGNORE, ce qui est à peu près ce que vous voulez), ou dans votre commande d'insertion:

INSERT OR IGNORE INTO Query... 

Si vous avez vous configurez la table avec la contrainte UNIQUE, vous avez vraiment pas besoin de changer votre requête INSERT (en plus de retirer le

peu WHERE NOT EXISTS certes laid. l'inconvénient est que, oui, il fait votre tentative de code toutes sortes d'insertions et Mais regardez-le dans l'autre sens: il fait en sorte que votre base de données se comporte comme vous le souhaitez, ce qui est essentiel pour travailler avec des bases de données, vous ne voulez pas effectuer une analyse manuelle complète de toutes les tables. 'ré faire une opération. Vous voulez laisser la base de données faire le sale boulot.

0

Dans votre question d'ignorer les doublons, vous devez enquêter sur DISTINCT

+0

Cela dans un INSERT en utilisant SELECT, je dois éviter les doublons ... – gremo

0

Je ne sais pas comment vous faites cela dans SQL Lite (s'il y en a problèmes de syntaxe spécifiques à la plate-forme qui est), mais la façon courante de supprimer les doublons est l'utilisation de GROUP BY.

W3Schools un assez bon exemple dans SQL générique:

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

L'autre option est DISTINCT, mais qui peut avoir des problèmes dans les grands ensembles de données. Enfin, en guise d'observation, vous pouvez envisager d'utiliser JOIN plutôt que des commandes SELECT imbriquées.

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

+0

INSÉRER O WH N'EXISTE PAS, pourquoi GROUP BY devrait être pertinent? – gremo

+0

Je suppose que j'aurais dû être un peu plus clair, un moyen courant d'éviter les doublons, lors de l'utilisation des jointures, est de regrouper par les attributs qui définissent l'égalité, puis de sélectionner le premier enregistrement. Cela ne fonctionnera pas dans votre scénario collé comme vos sélections imbriquées. –

Questions connexes