Power Query: como remover duplicatas e limpar dados
Guia prático de Power Query remover duplicatas e limpar dados: Remove Duplicates, Trim, Clean, substituir valores e o cuidado com a coluna certa.
Dados sujos derrubam seu relatório antes mesmo de você abrir o DAX
Quase todo problema de número errado que a gente investiga em cliente começa muito antes da medida. Começa na consulta. Um cadastro de clientes com o mesmo CNPJ digitado três vezes, um campo de estado com "SP", "sp" e " SP " convivendo na mesma coluna, linhas em branco herdadas de um Excel exportado torto. Quando isso chega ao modelo, o total infla, o relacionamento quebra e todo mundo perde confiança no dashboard.
Este é um passo a passo direto de Power Query remover duplicatas e limpar dados do jeito que fazemos em projeto real: com atenção à coluna certa, entendendo o que cada transformação faz de verdade e sabendo quando limpar na consulta e quando resolver na origem. Vai ter código M para você copiar e adaptar.
Remover duplicatas é fácil, remover a duplicata certa é o que importa
No Power Query, a opção Remove Duplicates (Remover Duplicatas) gera por baixo uma chamada a Table.Distinct. Ela mantém a primeira ocorrência de cada linha conforme a ordenação atual da tabela e descarta as demais. Guarde essa frase, porque é ela que causa a maior parte das dores: se você não controla a ordenação, você não controla qual linha sobrevive.
O primeiro cuidado é escolher em quais colunas a distinção acontece. São dois cenários bem diferentes:
- Selecionar uma coluna e remover duplicatas: o Power Query considera duplicada qualquer linha que repita o valor daquela coluna, ignorando o resto. Fica só uma linha por valor.
- Selecionar todas as colunas (ou nenhuma coluna específica) e remover duplicatas: só somem as linhas que são idênticas em todos os campos.
Confundir os dois é clássico. O time seleciona a coluna de e-mail, clica em Remove Duplicates achando que vai apenas tirar registros repetidos, e sem perceber joga fora pedidos legítimos que por acaso tinham o mesmo e-mail. Por isso a regra prática: antes de remover, pergunte qual é a chave do negócio.
// Remove duplicatas considerando SOMENTE a coluna CNPJ
// Fica uma linha por CNPJ, a primeira segundo a ordem atual
Table.Distinct(Origem, {"CNPJ"})
// Remove apenas linhas totalmente idênticas em todas as colunas
Table.Distinct(Origem)
Ordene antes de remover para escolher qual linha fica
Como Table.Distinct guarda a primeira ocorrência da ordenação vigente, ordenar a tabela antes vira o seu controle. Quer manter o cadastro mais recente de cada cliente? Ordene por data decrescente e só então remova duplicatas por CNPJ. A primeira linha de cada grupo passará a ser a mais nova.
let
Origem = Fonte,
// Ordena por data mais recente primeiro
Ordenado = Table.Sort(Origem, {{"DataCadastro", Order.Descending}}),
// Mantém a primeira de cada CNPJ, ou seja, a mais recente
SemDuplicatas = Table.Distinct(Ordenado, {"CNPJ"})
in
SemDuplicatas
Sem esse Table.Sort, você fica na mão da ordem em que os dados chegaram, que muda a cada atualização. Ordenar de propósito acaba com essa loteria.
Trim e Clean resolvem problemas invisíveis que quebram agrupamentos
Boa parte das "duplicatas" nem é duplicata de verdade. É sujeira de texto. "São Paulo" e "São Paulo " parecem iguais na tela, mas para o Power Query são valores distintos, porque um tem espaço no fim. Isso estraga agrupamentos, relacionamentos e contagens de valores distintos.
Duas transformações resolvem a maior parte disso, e é bom saber exatamente o que cada uma faz:
| Transformação | Função M | O que faz | O que NÃO faz |
|---|---|---|---|
| Trim | Text.Trim | Remove espaços do início e do fim do texto | Não remove espaços duplos no meio da palavra |
| Clean | Text.Clean | Remove caracteres não imprimíveis, como quebras de linha e tabulações ocultas | Não mexe em espaços comuns nas pontas |
| Lowercase | Text.Lower | Coloca tudo em minúsculas para padronizar | Não remove espaços nem acentos |
O ponto que mais confunde: Trim tira os espaços das pontas, mas não os internos. Se o seu dado tem "Rio de Janeiro" com espaço duplo no meio, o Trim não conserta. Para isso você precisa substituir os espaços múltiplos, o que veremos adiante.
O Clean, por sua vez, é o herói dos bugs invisíveis. Aquele caractere de quebra de linha que veio colado no fim de um código de produto não aparece na tela, mas separa dois registros que deveriam ser um só. Text.Clean remove esses caracteres não imprimíveis.
let
Origem = Fonte,
// Tira espaços das pontas da coluna Cidade
ComTrim = Table.TransformColumns(Origem, {{"Cidade", Text.Trim, type text}}),
// Remove caracteres invisíveis da mesma coluna
ComClean = Table.TransformColumns(ComTrim, {{"Cidade", Text.Clean, type text}}),
// Padroniza caixa para minúsculas em Cidade
Padronizado = Table.TransformColumns(ComClean, {{"Cidade", Text.Lower, type text}})
in
Padronizado
Uma sequência que recomendamos como padrão: primeiro Trim e Clean para tirar sujeira, depois Lowercase (ou uppercase) para padronizar a caixa, e só então remover duplicatas. Se você remove duplicatas antes de limpar, "SP" e " sp" seguem contando como dois. Limpe primeiro, deduplique depois.
Substituir valores conserta o que Trim e Clean não alcançam
Nem tudo é espaço nas pontas ou caractere oculto. Tem o espaço duplo no meio, o "N/A" que deveria ser vazio, o "S.A." e "SA" que precisam virar um padrão só. Para esses casos, a ferramenta é substituir valores, que no M é Text.Replace (por caractere ou trecho) ou Table.ReplaceValue (valor inteiro da célula).
// Troca dois espaços por um único, resolvendo o "espaço interno"
Table.TransformColumns(
Origem,
{{"Cidade", each Text.Replace(_, " ", " "), type text}}
)
// Substitui a célula inteira quando ela for exatamente "N/A" por nulo
Table.ReplaceValue(
Origem,
"N/A",
null,
Replacer.ReplaceValue,
{"Vendedor"}
)
A diferença entre os dois merece atenção. Text.Replace procura o trecho dentro do texto e troca onde encontrar. Table.ReplaceValue com Replacer.ReplaceValue troca a célula inteira apenas quando ela é exatamente igual ao valor buscado. Use Text.Replace para consertar pedaços do texto e Table.ReplaceValue para normalizar valores completos.
Para padronizar categorias que chegam bagunçadas, uma tabela mental ajuda a decidir a transformação:
| Problema no dado | Exemplo | Transformação certa |
|---|---|---|
| Espaço nas pontas | " SP " | Trim |
| Caractere invisível | "SP\n" | Clean |
| Maiúsculas e minúsculas misturadas | "sp" vs "SP" | Lowercase ou Uppercase |
| Espaço duplo interno | "Rio Grande" | Substituir " " por " " |
| Texto que deveria ser vazio | "N/A", "-" | Substituir por null |
| Variações de nome | "S.A." vs "SA" | Substituir valores |
Remover linhas em branco evita que o nada vire uma categoria
Planilhas exportadas costumam trazer linhas totalmente vazias, ou linhas em que só a chave está preenchida e o resto é nulo. Se você não tratar, o Power BI cria uma categoria em branco no gráfico e todo mundo pergunta "o que é esse (Em branco) aí?".
O botão Remove Blank Rows (Remover Linhas em Branco) tira linhas em que todas as colunas estão vazias. Ele gera por baixo uma combinação com Table.SelectRows. Para casos em que você quer filtrar por uma coluna específica que não pode ser nula, o filtro explícito é mais seguro:
// Remove linhas onde a coluna Produto é nula ou vazia
Table.SelectRows(
Origem,
each [Produto] <> null and [Produto] <> ""
)
Atenção a um detalhe: uma célula com espaço em branco (" ") não é o mesmo que vazia para o Power Query. Por isso, muitas vezes a ordem correta é aplicar Trim antes de remover linhas em branco. O Trim transforma " " em "", e aí o filtro de vazio finalmente pega.
Limpar na consulta ou na origem é uma decisão de arquitetura, não de gosto
Aqui está a pergunta que separa quem só arruma o relatório de hoje de quem constrói um dado sustentável: onde essa limpeza deveria morar?
Limpar dentro do Power Query é rápido, visual e ótimo para ajustes que dependem da lógica do relatório. Mas tem limite. Quando o mesmo CNPJ vem duplicado porque o sistema de origem permite cadastro repetido, você está tapando o buraco a cada atualização, para sempre. O certo, nesse caso, é corrigir na origem, seja no banco, no processo de cadastro ou numa camada de engenharia de dados que entregue o dado já tratado.
Um segundo motivo é técnico e chama query folding. Quando a fonte é um banco de dados, o Power Query consegue traduzir muitas transformações para SQL e empurrar o trabalho para o servidor. Isso é o folding. Limpezas feitas cedo na consulta, e antes de operações que quebram o folding, têm mais chance de rodar no banco, que é muito mais barato do que trazer tudo para a máquina e filtrar depois. A regra prática: filtre e reduza o quanto antes, porque limpeza feita cedo e com folding preservado custa menos.
Use esta referência para decidir:
| Situação | Onde limpar | Por quê |
|---|---|---|
| Duplicata causada por falha de cadastro na origem | Origem | Senão você remedia para sempre a cada carga |
| Padronizar caixa e espaços para este relatório | Power Query | Regra de apresentação, específica do modelo |
| Dado sujo usado por vários relatórios | Engenharia de dados | Trata uma vez, todos consomem limpo |
| Filtro de período e colunas desnecessárias | Power Query, cedo | Ajuda o folding e reduz volume |
Não existe resposta única. Existe a decisão consciente. Em projetos maiores, a limpeza estruturante fica numa camada central e o Power Query cuida só do ajuste fino, o que casa bem com uma boa modelagem no Power BI e com plataformas modernas como o Microsoft Fabric.
Um fluxo de limpeza que funciona na ordem certa
Juntando tudo, a sequência que aplicamos em consulta bem construída segue esta ordem:
- Filtre linhas e colunas que não vão ser usadas, o quanto antes, para preservar folding.
- Aplique Trim e Clean nas colunas de texto que servem de chave ou categoria.
- Substitua valores problemáticos: espaços duplos, "N/A", variações de nome.
- Padronize a caixa com Lowercase ou Uppercase onde for necessário agrupar.
- Remova linhas em branco, já com o Trim aplicado antes.
- Ordene a tabela pela regra que define qual linha deve sobreviver.
- Só então remova duplicatas, escolhendo a coluna certa como chave.
Repare que remover duplicatas é o último passo, não o primeiro. Deduplicar antes de limpar é o erro mais comum, porque o Power Query ainda enxerga "SP" e " sp " como diferentes e não remove nada de útil.
Perguntas frequentes
A opção Remove Duplicates do Power Query mantém qual linha?
Ela mantém a primeira ocorrência de cada valor conforme a ordenação atual da tabela, usando por baixo a função Table.Distinct. Como a ordem pode mudar entre atualizações, o jeito seguro de controlar qual linha fica é aplicar um Table.Sort antes, ordenando pela regra do negócio, por exemplo data mais recente primeiro.
Trim remove os espaços entre as palavras?
Não. O Trim, que é o Text.Trim, remove apenas os espaços do início e do fim do texto. Espaços duplos no meio, como em "Rio Grande", continuam lá. Para tirá-los, substitua a ocorrência de dois espaços por um, usando Text.Replace(_, " ", " ").
Qual a diferença entre Trim e Clean?
Trim cuida de espaços em branco nas pontas. Clean, que é o Text.Clean, remove caracteres não imprimíveis, como quebras de linha e tabulações que vêm ocultas e não aparecem na tela. Muitas duplicatas que parecem impossíveis de explicar são caracteres invisíveis que só o Clean resolve.
Devo remover duplicatas selecionando uma coluna ou todas?
Depende da chave. Se você seleciona só uma coluna, o Power Query mantém uma linha por valor daquela coluna e descarta o resto, mesmo que as outras colunas fossem diferentes. Se você não especifica coluna, ele só remove linhas idênticas em todos os campos. Antes de clicar, defina qual é a chave real do negócio.
É melhor limpar os dados no Power Query ou na origem?
Ajustes de apresentação específicos do relatório podem ficar no Power Query. Já problemas estruturais, como duplicatas causadas por falha de cadastro, devem ser resolvidos na origem ou numa camada de engenharia de dados, senão você refaz a correção a cada atualização. Limpezas feitas cedo na consulta também ajudam a preservar o query folding, tornando o processamento mais barato.
Como remover linhas em branco que na verdade têm espaços?
Uma célula com espaço não é considerada vazia pelo Power Query. Aplique o Trim primeiro, que transforma o espaço em texto vazio, e depois filtre com Table.SelectRows verificando se a coluna é diferente de null e de "". Assim as linhas que só tinham espaço também são removidas.
Feche o dado antes de abrir o dashboard
Remover duplicatas e limpar dados no Power Query não é um detalhe técnico, é o que sustenta a confiança no relatório. Escolha a coluna certa, ordene antes de deduplicar, use Trim e Clean para o que é invisível, substitua o que está fora do padrão e, acima de tudo, decida com consciência o que se limpa na consulta e o que se corrige na origem.
Se a sua base vive dando número errado e você suspeita que o problema começa antes do DAX, a gente ajuda a organizar isso da fonte ao painel. Conheça nossos serviços de Power BI e fale com a gente.
Quer aplicar isso na sua empresa?
A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.
Falar com um especialista