Waarom de Merge Node Onmisbaar is
In de echte wereld komt data zelden uit één bron. Je hebt klantgegevens in je CRM, bestellingen in je webshop, voorraad in je ERP, en reviews op externe platformen. De Merge node is de lijm die al deze data streams samenbrengt tot één coherent geheel.
Of je nu een simpele lijst wilt samenvoegen of complexe SQL joins moet uitvoeren tussen datasets, de Merge node heeft de tools die je nodig hebt. Met support voor tot onbeperkt aantal inputs sinds versie 1.49.0 en krachtige SQL query mogelijkheden, is dit een van de meest veelzijdige nodes in N8N.
De 4 Merge Modes: Van Simpel tot Complex
Mode 1: Append (Keep All Data) 📋
De simpelste vorm - voeg alle data samen, item voor item:
// Input 1: 3 customers
[
{ id: 1, name: "Jan", city: "Amsterdam" },
{ id: 2, name: "Piet", city: "Rotterdam" },
{ id: 3, name: "Klaas", city: "Utrecht" }
]
// Input 2: 2 suppliers
[
{ id: 101, company: "TechCo", product: "Software" },
{ id: 102, company: "DataCorp", product: "Analytics" }
]
// Output (Append): 5 items totaal
[
{ id: 1, name: "Jan", city: "Amsterdam" },
{ id: 2, name: "Piet", city: "Rotterdam" },
{ id: 3, name: "Klaas", city: "Utrecht" },
{ id: 101, company: "TechCo", product: "Software" },
{ id: 102, company: "DataCorp", product: "Analytics" }
]Use Cases:
- Consolideren van multiple data sources
- Aggregeren van resultaten van parallelle branches
- Verzamelen van data voor reporting
Mode 2: Combine - De Powerhouse 🔄
De meest flexibele mode met 3 combine strategieën:
A. Combine by Fields (Database Joins)
| Output Type | SQL Equivalent | Beschrijving | Use Case |
|---|---|---|---|
| Keep Matches | INNER JOIN | Alleen matching items | Order-customer koppeling |
| Keep Non-Matches | ANTI JOIN | Alleen non-matching | Vind ontbrekende data |
| Keep Everything | FULL OUTER JOIN | Alle items | Complete dataset |
| Enrich Input 1 | LEFT JOIN | Input 1 + matches | Verrijk hoofddata |
| Enrich Input 2 | RIGHT JOIN | Input 2 + matches | Verrijk secundaire data |
// Praktijkvoorbeeld: Customer enrichment met orders
// Input 1: Customers
[
{ customerId: 1, name: "Jan", email: "jan@example.com" },
{ customerId: 2, name: "Piet", email: "piet@example.com" },
{ customerId: 3, name: "Klaas", email: "klaas@example.com" }
]
// Input 2: Orders
[
{ orderId: 101, customerId: 1, amount: 150.00 },
{ orderId: 102, customerId: 1, amount: 75.50 },
{ orderId: 103, customerId: 2, amount: 200.00 }
]
// Merge Settings:
Mode: Combine
Combine By: Matching Fields
Fields to Match:
Input 1 Field: customerId
Input 2 Field: customerId
Output: Enrich Input 1
// Output: Customers enriched met order data
[
{
customerId: 1,
name: "Jan",
email: "jan@example.com",
orderId: 101,
amount: 150.00
},
{
customerId: 1,
name: "Jan",
email: "jan@example.com",
orderId: 102,
amount: 75.50
},
{
customerId: 2,
name: "Piet",
email: "piet@example.com",
orderId: 103,
amount: 200.00
},
{
customerId: 3,
name: "Klaas",
email: "klaas@example.com"
// Geen orders - maar customer blijft behouden
}
]B. Combine by Position (Index-based)
// Merge items op basis van hun positie in de array
// Input 1: Product names
[
{ product: "Laptop" },
{ product: "Mouse" },
{ product: "Keyboard" }
]
// Input 2: Prices
[
{ price: 999.99 },
{ price: 29.99 },
{ price: 79.99 }
]
// Output: Position-based merge
[
{ product: "Laptop", price: 999.99 }, // Index 0 + 0
{ product: "Mouse", price: 29.99 }, // Index 1 + 1
{ product: "Keyboard", price: 79.99 } // Index 2 + 2
]C. Multiplex (All Possible Combinations)
// Genereer alle mogelijke combinaties (Cartesian Product)
// Input 1: Sizes
[
{ size: "S" },
{ size: "M" },
{ size: "L" }
]
// Input 2: Colors
[
{ color: "Red" },
{ color: "Blue" }
]
// Output: All combinations (3 x 2 = 6 items)
[
{ size: "S", color: "Red" },
{ size: "S", color: "Blue" },
{ size: "M", color: "Red" },
{ size: "M", color: "Blue" },
{ size: "L", color: "Red" },
{ size: "L", color: "Blue" }
]Mode 3: Choose Branch 🚦
Selecteer welke input branch je wilt gebruiken:
// Conditionele branch selection
// Settings:
Mode: Choose Branch
Output: Input 2 // Kies specifieke input
// Use case: A/B testing of fallback scenarios
if (testCondition) {
// Use Input 1: Production data
return input1;
} else {
// Use Input 2: Test data
return input2;
}Mode 4: SQL Query (Advanced) 🔍
Sinds versie 1.49.0 - gebruik SQL voor complexe merges:
-- SQL Mode met multiple inputs
-- Input tables: input1, input2, input3, etc.
-- Voorbeeld 1: Complex join met aggregatie
SELECT
c.customerId,
c.name,
c.email,
COUNT(o.orderId) as totalOrders,
SUM(o.amount) as totalSpent,
AVG(o.amount) as avgOrderValue
FROM input1 c
LEFT JOIN input2 o ON c.customerId = o.customerId
GROUP BY c.customerId, c.name, c.email
ORDER BY totalSpent DESC;
-- Voorbeeld 2: Union met filtering
SELECT 'Customer' as type, name, email, city
FROM input1
WHERE active = true
UNION ALL
SELECT 'Supplier' as type, company as name, contact as email, location as city
FROM input2
WHERE verified = true;
-- Voorbeeld 3: Window functions
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) as rank,
SUM(quantity) OVER (PARTITION BY category) as categoryTotal
FROM input1;Advanced Options & Settings
Clash Handling
Wat gebeurt er als beide inputs dezelfde field names hebben?
| Option | Gedrag | Resultaat |
|---|---|---|
| Always Add Input Number | Voeg input nummer toe aan alle fields | name_1, name_2 |
| Prefer Input 1 Version | Gebruik waarde van Input 1 | Input 1 overwint |
| Prefer Input 2 Version | Gebruik waarde van Input 2 | Input 2 overwint |
Additional Options
- ✅ Fuzzy Compare: Behandel "3" en 3 als gelijk
- ✅ Disable Dot Notation: Voorkom parent.child field access
- ✅ Multiple Matches: Bepaal hoe om te gaan met meerdere matches
- ✅ Include Unpaired Items: Behoud items zonder match
Praktijkvoorbeeld: Complete E-commerce Data Pipeline
// Complete e-commerce data merge workflow
// Step 1: Products + Inventory merge
const merge1Config = {
mode: 'Combine',
combineBy: 'Matching Fields',
field1: 'sku', // Shopify SKU
field2: 'product_code', // Google Sheets code
output: 'Enrich Input 1',
options: {
fuzzyCompare: true,
multipleMatches: 'Include All Matches'
}
};
// Output: Products met real-time voorraad
const enrichedProducts = [
{
sku: "LAPTOP-001",
title: "Gaming Laptop",
price: 1299.99,
stock_quantity: 15, // Van Google Sheets
warehouse: "Amsterdam", // Van Google Sheets
reorder_point: 5 // Van Google Sheets
}
// ... meer producten
];
// Step 2: Add customer purchase data
const merge2Config = {
mode: 'SQL Query',
query: `
SELECT
p.*,
COUNT(DISTINCT c.customerId) as unique_buyers,
SUM(c.quantity) as total_sold,
AVG(c.order_value) as avg_order_value
FROM input1 p
LEFT JOIN input2 c ON p.sku = c.product_sku
GROUP BY p.sku
`
};
// Step 3: Add review aggregates
const merge3Config = {
mode: 'Combine',
combineBy: 'Matching Fields',
field1: 'sku',
field2: 'product_id',
output: 'Enrich Input 1',
additionalOptions: {
includeUnpaired: true // Producten zonder reviews behouden
}
};
// Final output: Complete 360° product view
const finalDataset = [
{
sku: "LAPTOP-001",
title: "Gaming Laptop",
price: 1299.99,
stock_quantity: 15,
warehouse: "Amsterdam",
unique_buyers: 45,
total_sold: 52,
avg_order_value: 1450.50,
review_count: 38,
avg_rating: 4.7,
recommendation_rate: 0.92
}
// Complete dataset voor analyse
];Performance Optimalisatie
Memory Management bij Grote Datasets
| Dataset Size | Recommended Mode | Optimization Tips |
|---|---|---|
| < 1000 items | Any mode | No optimization needed |
| 1000-10,000 items | Combine with indexing | Use field matching, avoid multiplex |
| 10,000-50,000 items | SQL mode | Use indexes, limit columns |
| > 50,000 items | Split & batch merge | Use Loop Over Items eerst |
Best Practices
- ✅ Index je match fields: Sorteer data op merge fields voor snellere matching
- ✅ Limit columns: Selecteer alleen benodigde fields vóór merge
- ✅ Avoid multiplex bij grote sets: Cartesian products exploderen snel
- ✅ Use SQL voor complexe logic: Efficiënter dan multiple merge nodes
- ✅ Monitor execution time: Check N8N execution logs
Common Use Cases & Patterns
1. Customer 360° View
// Merge customer data van alle touchpoints
Workflow:
1. CRM data (Input 1)
2. E-commerce orders (Input 2)
3. Support tickets (Input 3)
4. Email engagement (Input 4)
// Merge strategy:
- Merge 1+2: Enrich customers met orders
- Merge result+3: Add support history
- Merge result+4: Add engagement metrics
- Output: Complete customer profile2. Inventory Reconciliation
// Vergelijk voorraad tussen systemen
Workflow:
1. ERP inventory (Input 1)
2. Warehouse scans (Input 2)
3. Webshop stock (Input 3)
// Merge met Keep Non-Matches om discrepanties te vinden
Mode: Combine
Output: Keep Non-Matches
Result: Items met voorraadverschillen3. Multi-Channel Price Comparison
// Vergelijk prijzen across channels
SQL Query:
SELECT
sku,
webshop.price as web_price,
amazon.price as amazon_price,
bol.price as bol_price,
CASE
WHEN webshop.price < amazon.price THEN 'Web Cheaper'
WHEN amazon.price < webshop.price THEN 'Amazon Cheaper'
ELSE 'Same Price'
END as price_comparison
FROM input1 webshop
JOIN input2 amazon ON webshop.sku = amazon.sku
JOIN input3 bol ON webshop.sku = bol.sku;4. Data Deduplication
// Vind en merge duplicates
Workflow:
1. Original dataset
2. Same dataset (copy)
3. Merge met Keep Non-Matches
4. Identify unique records
// Of gebruik SQL:
SELECT DISTINCT * FROM input1
ORDER BY created_date DESC;Troubleshooting & Common Issues
Issue 1: Merge Node Wacht Niet op Alle Inputs
Probleem: Node executeert voordat alle inputs klaar zijn
Oplossing:
- Check workflow execution order (v0 vs v1)
- Gebruik 'Always Output Data' setting
- Verifieer dat alle input branches data produceren
Issue 2: Unexpected Output Count
Probleem: Meer/minder items dan verwacht
Oplossing:
// Debug je merge logic:
console.log('Input 1 count:', input1.length);
console.log('Input 2 count:', input2.length);
console.log('Expected output:', calculateExpected());
// Check voor:
- Multiple matches setting
- Include unpaired items setting
- Fuzzy compare creating unexpected matchesIssue 3: Field Name Conflicts
Probleem: Overlappende field names overschrijven data
Oplossing:
- Use 'Always Add Input Number' clash handling
- Rename fields voor merge
- Gebruik SQL mode voor precise control
Issue 4: Performance Issues
Probleem: Merge is traag bij grote datasets
Oplossing:
- Pre-sort data op match fields
- Gebruik SQL mode met indexes
- Split data in batches
- Remove onnodige fields voor merge
Advanced SQL Patterns
-- Pattern 1: Conditional merging
SELECT
CASE
WHEN i1.priority = 'high' THEN i1.*
ELSE i2.*
END as merged_data
FROM input1 i1
FULL OUTER JOIN input2 i2 ON i1.id = i2.id;
-- Pattern 2: Weighted averages
SELECT
product_id,
SUM(rating * weight) / SUM(weight) as weighted_avg_rating
FROM (
SELECT *, 1.5 as weight FROM input1 -- Recent reviews
UNION ALL
SELECT *, 1.0 as weight FROM input2 -- Older reviews
) combined
GROUP BY product_id;
-- Pattern 3: Time-based merging
SELECT
i1.*,
i2.update_data
FROM input1 i1
LEFT JOIN input2 i2 ON
i1.id = i2.id AND
i2.timestamp = (
SELECT MAX(timestamp)
FROM input2
WHERE id = i1.id
);
-- Pattern 4: Hierarchical merging
WITH RECURSIVE hierarchy AS (
SELECT * FROM input1 WHERE parent_id IS NULL
UNION ALL
SELECT i2.*
FROM input2 i2
JOIN hierarchy h ON i2.parent_id = h.id
)
SELECT * FROM hierarchy;Merge vs Alternative Approaches
| Method | Use Case | Pros | Cons |
|---|---|---|---|
| Merge Node | Standard data combining | Visual, flexible, no code | Limited to input count |
| Code Node | Complex transformations | Full control, any logic | Requires coding |
| Compare Datasets | Diff and sync | Built for comparison | Limited merge options |
| Database Query | Database-level joins | Best performance | Data must be in DB |
Best Practices Checklist
- ☑️ Understand je data structure voor merge
- ☑️ Kies de juiste merge mode voor je use case
- ☑️ Test met kleine datasets eerst
- ☑️ Handle field name conflicts proactief
- ☑️ Optimaliseer voor performance bij grote sets
- ☑️ Documenteer je merge logic
- ☑️ Implementeer error handling
- ☑️ Monitor output counts
- ☑️ Use SQL mode voor complexe requirements
- ☑️ Consider alternatives voor edge cases
Conclusie
De Merge node is de backbone van data integratie in N8N. Of je nu simpele lijsten combineert of complexe SQL joins uitvoert tussen meerdere bronnen, deze node heeft de flexibiliteit die je nodig hebt.
Met de nieuwe multi-input support en SQL capabilities is de Merge node geëvolueerd van een simpele combine tool naar een volwaardige data integration powerhouse. Master deze node, en je kunt vrijwel elke data challenge aan.
💡 Pro Tip: Begin met de Combine mode voor de meeste use cases. Als je meer controle nodig hebt, upgrade naar SQL mode. Gebruik Append alleen voor simpele concatenaties, en onthoud: Input 1 heeft altijd voorrang bij conflicts!