2012-12-24 1 views
1

Je ne suis pas à l'aise sur les requêtes SQL, mais j'essaie de créer une requête pour supprimer les données (commentaires rapportés) basées sur une jointure à une autre table (utilisateur) en utilisant un ID correspondance, voici un exemple de schéma ci-dessous:La suppression de l'ID de données SQL Server n'existe pas

create table tbl_reported_comment(id int, commentId int, reported_by_userid int); 

insert tbl_reported_comment values 
    (1, 1, 101), 
    (2, 2, 131), 
    (3, 3, 101), 
    (4, 4, 101), 
    (5, 5, 24), 
    (6, 6, 201), 
    (7, 7, 1), 
    (8, 8, 24), 
    (9, 9, 23), 
    (10, 10, 16), 
    (11, 11, 31); 

Create table tbl_user(userId int, Username varchar(50)); 

insert tbl_user values 
    (1, 'admin'), 
    (101, 'test1'), 
    (131, 'test2'), 
    (24, 'test3'), 
    (201, 'test4'); 

ce que je suis en train de réaliser dans ce cas est la suivante:

Retirez toutes les données dans la table tbl_reported_comment où la colonne [reported_by_userid] n'existe pas en tant que [userId] dans l'utilisateur Table

Voici un lien vers le SQLFIDDLE avec ce schéma exemple: SQLFiDDLE. J'utilise SQL Server comme base de données.

Un grand merci,

+1

La bonne façon de structurer votre base de données serait d'avoir une [clé étrangère] (http: // msdn .microsoft.com/fr-fr/library/ms175464 (v = sql.105) .aspx), ce qui rend la situation que vous êtes confronté à _impossible_. Une grande partie du but d'une base de données est d'assurer l'intégrité du référentiel et des données, c'est-à-dire qu'il est impossible que vos données soient erronées. – Ben

Répondre

3

Que pensez-vous de cela?

DELETE FROM dbo.tbl_reported_comment 
    OUTPUT DELETED.id, DELETED.commentId, DELETED.reported_by_userid 
    WHERE reported_by_userid NOT IN 
      (SELECT UserID FROM dbo.tbl_user) 

Cela supprimera les lignes et il affichera les lignes il supprimé à l'écran (dans SQL Server Management Studio) pour que vous puissiez voir ce qui a été supprimé. Et Ben a raison - une fois que vous avez fait cela, vous devez établir une relation de clé étrangère entre ces deux tables pour éviter les données de zombies comme ça dans le futur!

-- make your "UserID" column NOT NULL 
ALTER TABLE dbo.tbl_user 
ALTER COLUMN UserID INT NOT NULL 

-- so that we can use it as the PRIMARY KEY for that table! 
ALTER TABLE dbo.tbl_user 
ADD CONSTRAINT PK_user PRIMARY KEY CLUSTERED(UserID) 

-- so that we can then establish a FK relationship between those two tables.... 
ALTER TABLE dbo.tbl_reported_comment 
ADD CONSTRAINT FK_reported_comment_user 
FOREIGN KEY (reported_by_userid) REFERENCES dbo.tbl_user(UserID) 
+0

'NOT IN (SELECT DISTINCT ...)' sonne la sonnerie d'alarme dans ma tête. Est-ce vraiment nécessaire? Et un non existant ne serait-il pas meilleur qu'un non? – ErikE

+0

@ErikE: vous pourriez probablement aussi omettre le 'DISTINCT' - et non, je ne pense pas' SI NON EXISTS() 'serait toujours mieux. Parfois, une solution est plus rapide, une autre fois. Je préfère cette approche (mais il n'y a rien de mal avec le 'IF NOT EXISTS()' non plus) –

+0

Merci pour votre réponse. Je suis allé pour NOT EXISTS car il est probablement plus sûr d'utiliser dans le cas où il y a plus de 2000 valeurs pour la clause IN. –

0

Une sous-requête de remplacement en utilisant la fonction EXISTS serait la suivante:

DELETE x 
FROM tbl_reported_comment x 
WHERE 
    NOT EXISTS 
    (
    SELECT 1 
    FROM tbl_user y 
    WHERE 
     x.reported_by_userid = y.userId 
    ) 
Questions connexes