Para dos tablas, me gustaría comparar un conjunto determinado de columnas (dos en el ejemplo siguiente, pero podrían ser más) para ver si sus valores son idénticos.

El problema al que me enfrento es cuando las columnas contienen valores nulos (en el siguiente ejemplo me refiero a cuando var_1 y var_2 contienen valores nulos). En este ejemplo, una columna tiene formato de fecha y la otra es carácter, pero como esto puede variar, estoy tratando de evitar una solución que implique completar el nulo con algún valor.

Dado que la cantidad de columnas puede variar, idealmente me gustaría una solución que cuente las filas donde hay una falta de coincidencia o devuelva un resultado por fila.

Lo intenté por primera vez a continuación ...

SELECT SUM(a.var_1 = b.var_1, a.var_2 = b.var_2) AS result
FROM table_1 a
INNER JOIN table_2 b USING (key) 

... pero según otros SO publicaciones no se pueden agregar booleanos.

Luego probé un enfoque de unión con la idea de verificar los números de fila antes y después de la unión ...

SELECT COUNT(*)
FROM table_1 a
INNER JOIN table_2 b 
        ON a.key = b.key  
       AND a.var_1 = b.var_1
       AND a.var_2 = b.var_2

... pero esto solo une valores no nulos.

Finalmente intenté tener un cheque por fila

SELECT (a.var_1 = b.var_1) = (a.var_2 = b.var_2) AS result
FROM table_1 a
INNER JOIN table_2 b USING (key)

... pero cuando hay un nulo presente en la fila, el resultado es nulo.

Se agradecería cualquier ayuda sobre un mejor enfoque.

1
Sam Gilbert 13 dic. 2016 a las 21:44

2 respuestas

La mejor respuesta

Puede utilizar is not distinct from

SELECT COUNT(*)
FROM table_1 a
  JOIN table_2 b 
    ON a.key = b.key  
   AND (a.var_1, a.var_2) is not distinct from (b.var_1, b.var_2);

Si desea comparar todas las columnas de las tablas, puede simplificarlo para:

SELECT COUNT(*)
FROM table_1 a
  JOIN table_2 b 
    ON a is not distinct from b;
2
a_horse_with_no_name 13 dic. 2016 a las 18:46

¿Es esto lo que quieres?

SELECT SUM( (a.var_1 is not distinct from b.var_1 AND a.var_2 is not distinct from b.var_2)::int) AS result
FROM table_1 a INNER JOIN
     table_2 b
     USING (key) ;

El operador de Postgres estándar ANSI is not distinct from es un (bastante detallado) NULL - operador de igualdad seguro. Es decir, si dos valores son NULL, entonces devuelve verdadero en lugar de NULL.

1
Gordon Linoff 13 dic. 2016 a las 18:50