1

Trabajo con SQL Server 2008 necesito comparar valores entre dos tablas si los datos son iguales ponerle un equivalente.

Tengo el siguiente código de ejemplo:

declare @tmpEmpleado table (FirstName varchar(100));
Insert into @tmpEmpleado(FirstName)
values
('Nancy'), 
('Andrew'), 
('Janet'), 
('Steven');

DECLARE @Equivalencias TABLE(Nombre VARCHAR(100), NombreEquivalente VARCHAR(100))
INSERT into @Equivalencias(Nombre, NombreEquivalente) VALUES('Andrew', 'Batman')
,('Steven', 'Superman')
,('Nancy', ' ')

Comparo la tabla @tmpEmpleado con la tabla @Equivalencias si los valores del campo FirstName es igual a Nombre entonces ponerle el valor del campo NombreEquivalente de la tabla @Equivalencias, pero si en equivalencias es igual a '' poner el valor del campo FirstName, si FirstName no tiene valor de igualdad en el campo Nombre poner el valor de FirstName.

He intentado lo siguiente:

select FirstName,
case when temp.FirstName = equiVal.Nombre then equiVal.NombreEquivalente
when temp.FirstName = equiVal.Nombre and equiVal.NombreEquivalente = '' then temp.FirstName
when temp.FirstName = null then temp.FirstName
end as Equivalencia 
from @tmpEmpleado temp
join @Equivalencias equiVal on temp.FirstName = equiVal.Nombre

El resultado que espero es el siguiente:

Nancy    Nancy
Andrew   Batman
Janet    Janet
Steven   Superman
Pedro Ávila
  • 3,878
  • 9
  • 41
  • 102

3 Answers3

1

Tu solución está casi lista, simplemente unos cambios en la expresión CASE:

SELECT 
    t.FirstName,
    CASE
        WHEN LEN(e.NombreEquivalente) > 0 THEN e.NombreEquivalente
        ELSE t.FirstName
    END NombreEquivalente
FROM @tmpEmpleado t
LEFT JOIN @Equivalencias e
    ON t.FirstName = e.Nombre
;
Lamak
  • 7,971
  • 14
  • 24
1

En primer lugar, el join debiera ser un left join para que se incluyan todas las filas de la tabla de empleados aunque no haya coincidencias en la tabla de equivalencias.

Con esto hecho, se puede ajustar la cláusula case para que funcione como lo pides, creo que el código se auto explica:

select   temp.FirstName
       , case 
           when coalesce(ltrim(equiVal.NombreEquivalente), '') = '' then temp.FirstName
           else equiVal.NombreEquivalente
         end as Equivalencia 
from @tmpEmpleado temp
     left join @Equivalencias equiVal on temp.FirstName = equiVal.Nombre

**Edición: ** Aclarar que he incluido una llamada a ltrim() que puede no ser necesaria, depende de cuál haya sido el valor de la configuración ANSI_PADDING al momento de crear las tablas. Recomiendo al AP evaluar si la necesita o no en la base de datos real donde aplique esta solución.

jachguate
  • 25,659
  • 7
  • 35
  • 61
  • Si vas a comparar una cadena vacía, no necesitas usar `ltrim()`. – Luis Cazares Jul 08 '21 at 19:46
  • @Luis, llevas razón, lo incluí _por auto-reflejo_ al ver por allí que se inserta una cadena con un espacio, ahora veo que la columna es `varchar`, cosa que no verifiqué en el momento. – jachguate Jul 08 '21 at 19:49
  • 1
    Por otro lado, en el caso particular de SQL Server, tiendo a ser defensivo, por cosas como el `ANSI_PADDING`, con el que se puede lograr que el varchar almacene espacios, y siendo que se trata de SQL 2008, que solo dios sabe que default tenía, prefiero dejarlo en la respuesta, y que el AP lo quite si comprueba que no lo necesita. – jachguate Jul 08 '21 at 19:53
  • Creí que `coalesce` solo aplicaba con valores `NULL` pero veo que también funciona con '' – Pedro Ávila Jul 08 '21 at 19:57
  • 1
    no, el `coalesce` lo está usando para tu otra condición, que en caso que no haya valor en la tabla equivalencia se quede con el valor de FirstName – Lamak Jul 08 '21 at 19:59
  • El `Left Join` hace más lenta la consulta – Pedro Ávila Jul 08 '21 at 22:32
  • @Pedro, Explicate, ¿más lenta con respecto de qué? y ¿en qué te basas para decir que el _left join hace más lenta la consulta_? – jachguate Jul 09 '21 at 05:56
  • @jachguate la solución que me brindaste esta genial, mi comentario es porque tengo una query que le aplique el `LEFT JOIN` y esta query me trae 74308 rows, mi pregunta pasa de un mero comentario no es critica. – Pedro Ávila Jul 09 '21 at 19:29
0

Existe una forma sencilla de hacer manejando simplemente valores nulos.

SELECT FirstName, 
    ISNULL( NULLIF( equiVal.NombreEquivalente, ''), temp.FirstName) as Equivalencia 
FROM @tmpEmpleado temp
LEFT
JOIN @Equivalencias equiVal on temp.FirstName = equiVal.Nombre;

Cambiamos el INNER JOIN por un LEFT JOIN para poder obtener todas las filas de la tabla empleado. Los nombres sin una equivalencia quedarán con un equivalente nulo. Después agregamos la función ISNULL() para que convierta las cadenas vacías en nulos. No hace falta hacer comparación entre el primer nombre y nombre de la tabla de equivalencias porque ya lo hicimos en el JOIN.

Luis Cazares
  • 7,775
  • 1
  • 6
  • 18