ROW_NUMBER() — O canivete suíço do SQL no SFMC
Deduplicação, seleção do estado mais recente e ranking determinístico.
O nível de evidência descreve minha experiência com o conteúdo. Fonte oficial descreve contrato/documentação da plataforma. Observação de produção não deve ser tratada automaticamente como limite oficial.
Use ROW_NUMBER() quando a pergunta de negócio for “qual única linha deve sobreviver dentro de cada grupo lógico?”. A parte difícil não é a função — é definir corretamente a partição e a regra de ordenação.
PARTITION BY define a identidade de negócio ou o grupo.
ORDER BY define qual linha vence dentro desse grupo.
Adicione um desempate determinístico quando o critério principal puder empatar.
Filtre o rn fora do SELECT que contém a window function, normalmente com rn = 1.
Não particione por um campo conveniente se ele não representar a chave real de negócio.
Padrão canônico
A query interna ranqueia as linhas. A query externa escolhe a vencedora. Essa separação deixa a lógica legível e permite inspecionar o ranking durante troubleshooting.
SELECT
SubscriberKey,
EmailAddress,
ModifiedDate
FROM (
SELECT
SubscriberKey,
EmailAddress,
ModifiedDate,
ROW_NUMBER() OVER (
PARTITION BY SubscriberKey
ORDER BY ModifiedDate DESC, RecordID DESC
) AS rn
FROM [Source_DE]
) ranked
WHERE rn = 1A partição é a regra de negócio
PARTITION BY SubscriberKey significa “uma vencedora por subscriber”. PARTITION BY EmailAddress significa “uma vencedora por email”. Esses dois modelos de identidade não são intercambiáveis.
Ao consolidar marcas ou fontes, a chave de partição precisa refletir a regra de identidade que você realmente está implementando — não apenas a coluna que por acaso está preenchida.
Desempates importam
Se duas linhas tiverem o mesmo ModifiedDate, o SQL pode devolver qualquer uma primeiro se nenhum segundo critério determinístico resolver o empate.
Um ID estável de registro, prioridade de fonte, timestamp de criação ou prioridade explícita de negócio pode virar a segunda expressão do ORDER BY.
ROW_NUMBER() OVER (
PARTITION BY SubscriberKey
ORDER BY
ModifiedDate DESC,
CASE Source
WHEN 'MASTER' THEN 1
WHEN 'CRM' THEN 2
ELSE 9
END ASC,
RecordID DESC
) AS rnSe você não consegue explicar por que a linha A vence a linha B, a regra de deduplicação ainda não terminou.
ROW_NUMBER também é ferramenta de diagnóstico
Mantenha o rn em uma saída temporária enquanto valida a regra. Linhas com rn = 2, 3, 4 mostram o que está sendo descartado e frequentemente revelam duplicidades inesperadas ou premissas fracas de identidade.
Mantenha a linha mais recente para cada identidade lógica usando ROW_NUMBER().
Torne a deduplicação determinística quando o timestamp principal puder empatar.
Use ROW_NUMBER() como ferramenta de histórico/debug, não apenas para rn = 1.