2 votes

Spark / Scala - Comparer deux colonnes dans un Dataframe quand l'une d'entre elles est NULL

J'utilise Spark (Scala) pour contrôler les mouvements de données - déplacer des tables d'une base de données relationnelle à une autre. Le processus d'assurance qualité implique l'exécution d'une jointure externe complète entre la table source et la table cible.

La table source et les tables cibles sont jointes dans un cadre de données sur la (les) clé(s) :

val joinColumns = for (i <- 0 to (sourceJoinFields.length - 1)) yield sourceDF.col(sourceJoinFields(i)) <=> targetDF.col(targetJoinFields(i))
val joinedDF = sourceDF.join(targetDF, joinColumns.reduce((_&&_)), "fullouter")

J'utilise la logique suivante pour trouver les erreurs de correspondance :

val mismatchColumns = for (i <- 0 to (sourceDF.columns.length-1)) yield (joinedDF.col(joinedDF.columns(i)) =!= joinedDF.col(joinedDF.columns(i+(sourceDF.columns.length))))
val mismatchedDF = joinedDF.filter(mismatchColumns.reduce((_||_)))

Cependant, si une clé manque d'un côté de la jointure externe complète :

+--------------+--------------+--------------+--------------+
|source_key    |source_field  |target_key    |target_field  |
+--------------+--------------+--------------+--------------+
|null          |null          |XXX           |XXX           |

ne figurera pas dans l'ensemble des données de la FAD non concordante.

Ma question est donc la suivante : le =!= l'inverse de l'opérateur <=> opérateur ? Il ne semble pas que ce soit le cas, alors existe-t-il un opérateur qui renverra FALSE dans ce cas ? Je ne trouve pas beaucoup de documentation sur l'un ou l'autre de ces opérateurs.

4voto

user6910411 Points 32156

Le contraire de IS NOT DISTINCT FROM ( <=> ) est IS DISTINCT FROM ( not(... <=> ...) ).

import org.apache.spark.sql.not

val df = Seq(("foo", null), ("foo", "bar"), ("foo", "foo")).toDF("x", "y")
df.select(not($"x" <=> $"y"))

o

df.select(!($"x" <=> $"y"))

o

df.selectExpr("x IS DISTINCT FROM y")

tous donnent le même résultat :

+---------------+
|(NOT (x <=> y))|
+---------------+
|           true|
|           true|
|          false|
+---------------+

Bien sûr, si vous avez une disjonction de négations :

(NOT P) OR (NOT Q)

vous pouvez toujours utiliser les lois de De Morgan pour le réécrire comme une négation de concjonctions

NOT(P AND Q)

donc :

not(joinColumns.foldLeft(lit(true))(_ and _))

devrait fonctionner parfaitement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X