2017-01-08 36 views

Odpowiedz

11

Przede wszystkim nie używaj kodu null w swoim kodzie Scala, chyba że naprawdę musisz z powodu kompatybilności.

Jeśli chodzi o twoje pytanie, jest to zwykły kod SQL. col("c1") === null jest interpretowany jako c1 = NULL, a ponieważ NULL oznacza niezdefiniowane wartości, wynik jest niezdefiniowany dla dowolnej wartości, w tym samej NULL.

spark.sql("SELECT NULL = NULL").show 
+-------------+ 
|(NULL = NULL)| 
+-------------+ 
|   null| 
+-------------+ 
spark.sql("SELECT NULL != NULL").show 
+-------------------+ 
|(NOT (NULL = NULL))| 
+-------------------+ 
|    null| 
+-------------------+ 
spark.sql("SELECT TRUE != NULL").show 
+------------------------------------+ 
|(NOT (true = CAST(NULL AS BOOLEAN)))| 
+------------------------------------+ 
|        null| 
+------------------------------------+ 
spark.sql("SELECT TRUE = NULL").show 
+------------------------------+ 
|(true = CAST(NULL AS BOOLEAN))| 
+------------------------------+ 
|       null| 
+------------------------------+ 

wyłącznie ważny metod, aby sprawdzić NULL są:

  • IS NULL:

    spark.sql("SELECT NULL IS NULL").show 
    
    +--------------+ 
    |(NULL IS NULL)| 
    +--------------+ 
    |   true| 
    +--------------+ 
    
    spark.sql("SELECT TRUE IS NULL").show 
    
    +--------------+ 
    |(true IS NULL)| 
    +--------------+ 
    |   false| 
    +--------------+ 
    
  • IS NOT NULL:

    spark.sql("SELECT NULL IS NOT NULL").show 
    
    +------------------+ 
    |(NULL IS NOT NULL)| 
    +------------------+ 
    |    false| 
    +------------------+ 
    
    spark.sql("SELECT TRUE IS NOT NULL").show 
    
    +------------------+ 
    |(true IS NOT NULL)| 
    +------------------+ 
    |    true| 
    +------------------+ 
    

realizowane w DataFrame DSL jako Column.isNull i Column.isNotNull odpowiednio.

0

Zazwyczaj najlepszym sposobem, aby rzucić światło na nieoczekiwane wyniki w Spark Dataframes jest spojrzenie na plan wyjaśniający. Rozważmy następujący przykład:

import org.apache.spark.sql.{DataFrame, SparkSession} 
import org.apache.spark.sql.functions._ 

object Example extends App { 

    val session = SparkSession.builder().master("local[*]").getOrCreate() 
    case class Record(c1: String, c2: String) 
    val data = List(Record("a", "b"), Record(null, "c")) 
    val rdd = session.sparkContext.parallelize(data) 
    import session.implicits._ 

    val df: DataFrame = rdd.toDF 
    val filtered = df.filter(col("c1") === null) 
    println(filtered.count()) // <-- outputs 0, not expected 

    val filtered2 = df.filter(col("c1").isNull) 
    println(filtered2.count()) 
    println(filtered2) // <- outputs 1, as expected 

    filtered.explain(true) 
    filtered2.explain(true) 
} 

Pierwszy wyjaśnić Plan pokazuje:

== Physical Plan == 
*Filter (isnotnull(c1#2) && null) 
+- Scan ExistingRDD[c1#2,c2#3] 
== Parsed Logical Plan == 
'Filter isnull('c1) 
+- LogicalRDD [c1#2, c2#3] 

Ten filtr klauzula wygląda bezsensowne. Dzięki temu && do null nigdy nie zostanie rozwiązane na true.

Drugi wyjaśnić Plan wygląda następująco:

== Physical Plan == 
*Filter isnull(c1#2) 
+- Scan ExistingRDD[c1#2,c2#3] 

Tutaj filtr ma co oczekiwać i chcą.

+0

Przepraszam, nie mogłem zrozumieć jednej rzeczy. Dlaczego otrzymuję rekordy, gdy używam ===. Jak to będzie możliwe @mattinbits – John

+0

Czy twoje dane rzeczywiście mają "null" w tej kolumnie? – mattinbits

+0

Ma kilka pustych rekordów (""), ale liczba zwracanych rekordów nie pasuje do pustego łańcucha, gdy używam === null. Będzie miał puste i niepuste rekordy. Ale otrzymuję wyjątek wskaźnika NULL podczas wywoływania pakietu udf, który nie ma zerowej kontroli. – John