En plataformas como Salesforce Marketing Cloud (SFMC), es común tener una Data Extension con múltiples registros por usuario. Esto pasa especialmente cuando la DE está construida sobre transacciones, donde la clave primaria es un order_id
o algo equivalente. En estos casos, el mismo email puede aparecer muchas veces.
El requerimiento
Queremos deduplicar esta DE para obtener una sola fila por usuario, quedándonos solo con la fecha de transacción más reciente.
Caso 1: Solo necesitas el email y la fecha más reciente
Si no necesitas traer otras columnas, la forma más eficiente es usar MAX()
en combinación con GROUP BY
:
SELECT
email,
MAX(purchase_dt) AS latest_purchase_dt
FROM
your_orders_de
GROUP BY
email
Este query agrupa todos los registros por email
y devuelve la fecha más reciente de compra por cada uno. Perfecto para segmentaciones o audiencias simples.
Caso 2: Necesitas columnas adicionales de la última transacción
Si además de la fecha quieres traer datos como el order_id
, el producto, el monto o cualquier otro campo asociado con esa transacción específica, MAX()
ya no te sirve directamente.
Aquí necesitas usar un subquery que te devuelva solo la fila más reciente por usuario, y para eso puedes combinar ROW_NUMBER()
con una subconsulta:
SELECT
email,
order_id,
purchase_dt,
product_name,
amount
FROM (
SELECT
email,
order_id,
purchase_dt,
product_name,
amount,
ROW_NUMBER() OVER (PARTITION BY email ORDER BY purchase_dt DESC) AS rn
FROM
your_orders_de
) AS ranked
WHERE rn = 1
Este patrón te garantiza una sola fila por usuario, con todos los datos correspondientes a su transacción más reciente.
¿Cuál deberías usar?
Depende del caso:
- Usa
GROUP BY + MAX()
si solo necesitas el campo deduplicado (como la fecha más reciente). - Usa
ROW_NUMBER()
si necesitas más columnas del mismo registro.
Ambos patrones son muy útiles en SFMC, especialmente cuando construyes audiencias para journeys o campañas que dependen del comportamiento más reciente del usuario.
Bonus Track
Si tienes millones de registros y tu query se queda pasmada o stallea, no intentes traer todo de un jalón. Hazlo por partes:
- Usa un
SELECT TOP 1000
sobre tu tabla origen. - Agrega una condición tipo:
WHERE user_id NOT IN (SELECT user_id FROM target_de)
- Configura tu query en Automation Studio como append, no como overwrite.
Así, cada vez que se ejecute, irá trayendo 1000 registros que aún no están en la target DE, hasta que completes el total.
Sí: es como arrastrarse por el lodo. Pero llegarás.
¿Tienes muchos duplicados? ¿No sabes cuál transacción tomar como referencia? En esos casos, una buena estrategia SQL puede hacer toda la diferencia entre una campaña eficiente y un desastre de datos.
Aclaración:
Esto no es una fórmula y los nombres no tiene por qué ser siempre iguales. Mantente dentro de tu naming convention y si no la tienes: genérala. Recuerda: ABD. Always Be Documenting.