Append in SQL: nieuwe records toevoegen zonder dubbele data
Blogs over SQL
SQL cursus voor beginners
Leestijd
5 minuten
Auteur
Robin van Hattum
Stel, je krijgt een actuele productlijst binnen. Die data moeten naar je doeltabel. Maar hoe doe je dat zonder dubbele records of weggegooide informatie?
Alles opnieuw laden kan. Dat heet overwrite. Soms prima, maar bij een doeltabel voor rapportages, controles of verdere verwerking wil je meestal voorzichtiger zijn.
In deze blog kijk je daarom naar append in SQL: alleen toevoegen wat nog ontbreekt. Bestaande records blijven staan, nieuwe records worden toegevoegd, en dezelfde producten belanden niet twee keer in je doeltabel.
De kernvraag: welke records staan wel in de bron, maar nog niet in de doeltabel?
Situatie
We gebruiken twee tabellen. Bron.Producten bevat de actuele productlijst. Doel.DimProduct bevat de producten die eerder al zijn geladen. ProductID is de sleutel waarmee we bepalen of een product al bestaat.
Begrip en korte uitleg
Bron: de tabel of het systeem waar de actuele data vandaan komt.
Doel: de tabel waar de data naartoe wordt geladen.
Overwrite: de doeltabel volledig vervangen door de bron.
Append: alleen nieuwe records toevoegen; bestaande records blijven staan.
Anti-join: een vergelijking waarmee je rijen vindt die wel links bestaan, maar rechts niet.
NOT EXISTS: een controle waarmee je test of een bijbehorende rij ontbreekt.
Belangrijke spelregel: append is alleen voldoende als bestaande records niet hoeven te worden bijgewerkt. Kunnen productnamen, prijzen of categorieën wijzigen? Dan heb je later ook update- of upsert-logica nodig. Dat pakken we in de volgende blog/video op.
Maak eerst schema’s en tabellen aan en vul deze met data:
Schema’s aanmaken
CREATE SCHEMA Bron;
GO
CREATE SCHEMA Doel;
GO
Tabellen aanmaken
CREATE TABLE Bron.Producten
(
ProductID INT NOT NULL PRIMARY KEY,
ProductNaam VARCHAR(50) NOT NULL,
Categorie VARCHAR(30) NOT NULL,
Prijs DECIMAL(10,2) NOT NULL
);
CREATE TABLE Doel.DimProduct
(
ProductID INT NOT NULL PRIMARY KEY,
ProductNaam VARCHAR(50) NOT NULL,
Categorie VARCHAR(30) NOT NULL,
Prijs DECIMAL(10,2) NOT NULL
);
Brontabel vullen met data
INSERT INTO Bron.Producten(ProductID, ProductNaam, Categorie, Prijs)
VALUES (1, ‘Laptopstandaard’, ‘Accessoires’, 39.95)
, (2, ‘Draadloze muis’, ‘Accessoires’, 24.95)
, (3, ‘USB-C hub’, ‘Accessoires’, 49.95)
, (4, ‘Monitor 27 inch’, ‘Beeldschermen’, 229.00)
, (5, ‘Compact toetsenbord’, ‘Accessoires’, 59.95)
, (6, ‘Webcam Full HD’, ‘Camera’, 79.95)
, (7, ‘Noise cancelling headset’, ‘Audio’, 149.00);
Doeltabel vullen met data
INSERT INTO Doel.DimProduct(ProductID, ProductNaam, Categorie, Prijs)
SELECT ProductID, ProductNaam, Categorie, Prijs
FROM Bron.Producten;
Nieuw product toevoegen aan brontabel
INSERT INTO Bron.Producten(ProductID, ProductNaam, Categorie, Prijs)
VALUES (8, ‘Laptop rugtas’, ‘Accessoires’, 69.95);
Datasets testen
SELECT Count(*) AS AantalProducten — Een nieuw product
FROM bron.producten
SELECT Count(*) AS AantalProducten
FROM doel.dimproduct
Stap 1 – Overwrite als eenvoudige maar grove methode
DELETE FROM Doel.DimProduct;
INSERT INTO Doel.DimProduct
( ProductID, ProductNaam, Categorie, Prijs )
SELECT ProductID, ProductNaam, Categorie, Prijs
FROM Bron.Producten;
Dit is de overwrite-aanpak: eerst leegmaken, daarna opnieuw vullen. Lekker simpel, maar ook grof. Alles wat al in de doeltabel stond, wordt eerst verwijderd. Als je doeltabel inmiddels wordt gebruikt of is verrijkt, kan dat precies de rommel veroorzaken die je wilde voorkomen.
Stap 2 – Nieuwe records zichtbaar maken met een anti-join
SELECT b.ProductID, b.ProductNaam, b.Categorie, b.Prijs
FROM Bron.Producten AS b
LEFT JOIN Doel.DimProduct AS d
ON b.ProductID = d.ProductID
WHERE d.ProductID IS NULL;
Met een LEFT JOIN houd je alle producten uit de bron zichtbaar. Voor producten die al in de doeltabel staan, vindt SQL een match. Voor nieuwe producten is die match er niet. Door te filteren op WHERE d.ProductID IS NULL houd je precies de ontbrekende producten over.
Stap 3 – Dezelfde controle met NOT EXISTS
SELECT b.ProductID, b.ProductNaam, b.Categorie, b.Prijs
FROM Bron.Producten AS b
WHERE NOT EXISTS
( SELECT 1
FROM Doel.DimProduct AS d
WHERE d.ProductID = b.ProductID
);
NOT EXISTS doet dezelfde controle, maar leest vaak dichter op de bedoeling: voeg dit bronrecord alleen toe als er nog geen bijbehorend record in de doeltabel bestaat. SQL kijkt dus per bronrij: bestaat dit ProductID al? Zo niet, dan blijft de rij over.
Stap 4 – Nieuwe records toevoegen
INSERT INTO Doel.DimProduct
( ProductID, ProductNaam, Categorie, Prijs )
SELECT b.ProductID, b.ProductNaam, b.Categorie, b.Prijs
FROM Bron.Producten AS b
WHERE NOT EXISTS
( SELECT 1 FROM Doel.DimProduct AS d
WHERE d.ProductID = b.ProductID
);
Het SELECT-statement bepaalt welke producten nieuw zijn. INSERT INTO gebruikt dat resultaat direct om alleen die nieuwe producten weg te schrijven naar de doeltabel.
Toepassing
Append is handig wanneer brondata stap-voor-stap binnenkomt. Denk aan nieuwe orders, nieuwe metingen, nieuwe klanten of nieuwe producten. Maar append werkt alleen voor nieuwe records. Wijzigt een bestaand product later? Dan heb je ook update- of upsert-logica nodig. Dat zie je de volgende blog/video: de upsert-methode. Wil je SQL gebruiken om data betrouwbaar te vergelijken, te laden en te controleren? In onze SQL-trainingen bouw je dit soort oplossingen stap-voor-stap op. In onze trainingen verbinden we theorie direct aan de praktijk.