n8n 교재 · 중급 15편

n8n Merge 노드 — Append · Combine · SQL Join

두 데이터 스트림을 합치는 4가지 방식, 그리고 매칭 키 함정. 5분 안에 머릿속 정리.

두 평행 데이터 흐름이 Y자 노드에서 하나로 합쳐지는 일러스트 — n8n Merge 컨셉

워크플로가 복잡해지면 자연스럽게 두 갈래 데이터가 생긴다. "Sheets 의 사용자 목록 + Postgres 의 결제 정보를 합쳐서 Slack 으로 보내기" 같은 흔한 시나리오. 이때 쓰는 노드가 Merge — 그런데 4가지 모드가 있어서 처음엔 어느 걸 골라야 할지 헷갈린다.

15편에서는 4 모드의 차이를 SQL Join 과 1:1 매핑하고, 매칭 키를 잘못 잡았을 때 일어나는 사고를 짚는다. 실전에서 두 스트림 합치는 패턴이 손에 잡힌다.

1. Merge 4 모드 — SQL Join 과 1:1 대응

Merge 노드 첫 옵션 Mode 가 모든 걸 결정한다. 4개 중 하나, 그리고 Combine 모드 안에 또 5개 하위 옵션.

모드SQL 대응언제 쓰나
AppendUNION ALL두 스트림을 그냥 이어붙임. 매칭 안 함. 예: 여러 채널 알림 합쳐 한 큐로
Combine: Keep MatchesINNER JOIN양쪽에 다 존재하는 row 만. "결제 완료 + 발송 대기" 교집합
Combine: Keep Non-MatchesFULL OUTER JOIN minus INNER차집합. "Sheets 에는 있는데 DB 에 없는 사용자" 찾을 때
Combine: Keep EverythingFULL OUTER JOIN합집합 전체. 두 소스 통합 보고서
Combine: Enrich Input 1LEFT JOIN왼쪽 다 보존 + 오른쪽 매칭만 붙임. 가장 자주 씀 (메인 + 보조 정보)
Combine: Enrich Input 2RIGHT JOIN오른쪽 다 보존 + 왼쪽 매칭만. 잘 안 씀 (Enrich Input 1 + 입력 순서 바꾸면 동일)
SQL Query자유 SQL위 6개로 안 되는 복잡한 join·집계. input1·input2 가상 테이블
Choose BranchCASE WHEN실제 합치진 않고 두 입력 중 하나만 통과시킴. IF 노드 보완용
실전 90%는 두 가지 — 새 row 누적은 Append, 두 소스 매칭 결합은 Enrich Input 1. 나머지는 가끔 쓴다. 처음엔 이 둘만 마스터해도 충분.

2. 매칭 키 (Fields to Match) — 함정 3개

Combine 모드를 고르면 "Fields to Match" 필드가 나온다. 어떤 필드로 양쪽 데이터를 매칭할지 지정. 여기가 가장 자주 실수하는 자리.

함정 1 — 대소문자·공백 불일치

한쪽은 email: "[email protected] ", 다른 쪽은 email: "[email protected]" 이면 매칭 안 됨. n8n Combine 은 strict equality. 매칭 직전에 Set 노드로 정규화:

={{ ($json.email || '').trim().toLowerCase() }}

이 작업을 Merge 노드 직전에 항상 끼는 게 안전. 14편 Loop 처럼 다량 처리할수록 누락 발견이 늦어진다.

함정 2 — 중복 키로 N×M 폭발

Input 1 에 같은 키가 3개, Input 2 에 같은 키가 5개면 결과는 15 row. 의도였으면 OK, 아니면 데이터가 부풀어오른다. 매칭 키는 양쪽 모두 UNIQUE 인 컬럼이 원칙. 안 그러면 Merge 직전에 Remove Duplicates 노드로 미리 정리.

함정 3 — 타입 불일치 (string vs number)

한쪽은 user_id 가 문자열 "123", 다른 쪽은 숫자 123 이면 매칭 안 됨. JSON 에서 흔히 발생 — Sheets 는 모두 문자열, Postgres 는 숫자. Set 노드로 한쪽을 변환:

={{ Number($json.user_id) }}

디버깅 팁 — Combine 결과가 비어있으면 Merge 실행 후 Input 1·2 의 첫 row 를 각각 Set 노드로 띄워서 "키 컬럼 값 + 타입" 을 눈으로 확인. typeof $json.user_id 표현식으로 string/number 차이도 한 번에 보임.

3. 실전 시나리오 — Sheets + Postgres 합치기

예시 워크플로: "Google Sheets 의 가입 사용자 목록 (이메일·이름) + Postgres 의 결제 이력 (이메일·총결제액) → 결제액 별로 등급 분류 후 Slack 알림".

  1. Schedule (매일 자정) → 트리거
  2. Google Sheets Read → user_list 시트 전체 가져오기 (Input 1)
  3. Postgres Execute QuerySELECT email, SUM(amount) AS total FROM payments GROUP BY email (Input 2)
  4. Set (Input 1) → email 정규화: ={{ ($json.email||'').trim().toLowerCase() }}
  5. Set (Input 2) → 동일하게 email 정규화 + total 을 Number 로 변환
  6. Merge → Mode: Combine / Output Type: Enrich Input 1 / Fields to Match: email
  7. Switch → total 별 분기 (≥100만 VIP, ≥10만 일반, 미만 신규)
  8. Slack → 각 분기마다 다른 채널 알림

핵심은 노드 4·5번 — Merge 직전에 항상 정규화 Set 을 끼는 패턴. 양쪽 데이터 소스의 형식 차이가 누락의 99%다. 18편 Postgres 의 RETURNING 패턴과 합치면 "방금 들어온 신규 결제만 합쳐서 알림" 같은 실시간 처리도 가능.

4. SQL Query 모드 — 언제 필수인가

위 8가지 옵션으로도 안 되는 케이스가 있다. 3개 이상 입력을 한 번에 join 하거나, 집계 (GROUP BY · 윈도우 함수) 가 필요한 경우. 이때 SQL Query 모드.

입력 N개가 input1·input2·input3 가상 테이블로 들어온다 (n8n 내부에 SQLite 가 돌아감). 예 — 사용자 + 결제 + 환불 3 소스를 합쳐 순이익 계산:

SELECT u.email, u.name, COALESCE(p.total,0) - COALESCE(r.total,0) AS net
FROM input1 AS u
LEFT JOIN input2 AS p ON p.email = u.email
LEFT JOIN input3 AS r ON r.email = u.email;

장점 — 익숙한 SQL 문법. 단점 — 큰 데이터는 SQLite 메모리 한계 (수십만 row 부터 느려짐). 그 규모면 18편 Postgres 직접 쿼리가 답.

다음 글

n8n 교재 16편 — Sub-Workflow + Execute Workflow. 위 Merge 패턴을 재사용 모듈로 분리해 DRY 워크플로 짜기.

© 2026 주나이테크(주) @JUNAITECH