【问题标题】:Can Spark SQL not count correctly or can I not write SQL correctly?Spark SQL 不能正确计数或者我不能正确编写 SQL 吗?
【发布时间】:2018-08-22 05:57:54
【问题描述】:

在 Databricks“社区版”上的 Python 笔记本中,我正在试验旧金山市有关向 911 请求消防员的紧急呼叫的开放数据。 ("Using Apache Spark 2.0 to Analyze the City of San Francisco's Open Data" (YouTube) 中使用的 2016 年旧数据副本,并在 S3 上为该教程提供。)

在装载数据并使用显式定义的架构将其读取到 DataFrame fire_service_calls_df 后,我将该 DataFrame 别名为 SQL 表:

sqlContext.registerDataFrameAsTable(fire_service_calls_df, "fireServiceCalls")

有了它和 DataFrame API,我可以计算发生的调用类型:

fire_service_calls_df.select('CallType').distinct().count()
Out[n]: 34

...或使用 Python 中的 SQL:

spark.sql("""
SELECT count(DISTINCT CallType)
FROM fireServiceCalls
""").show()
+------------------------+
|count(DISTINCT CallType)|
+------------------------+
|                      33|
+------------------------+

...或使用 SQL 单元格:

%sql

SELECT count(DISTINCT CallType)
FROM fireServiceCalls

为什么我会得到两个不同的计数结果?(似乎 34 是正确的,尽管 talk in the video 和随附的教程笔记本提到“35 "。)

【问题讨论】:

  • 如果你的 CallType 是一个字符串,你能检查一下 SQL 是否正在(或不是)使 charvarchar 区别?当您计算不同的修剪值时会发生什么?
  • SQL 中不同的计数通常会忽略空值。我敢打赌 DataFrame 会将它们视为不同的值。
  • 只有 30 个值,您可以对所有不同的项目进行排序和打印,以查看差异在哪里。
  • @CharlesC 似乎是对的:NULL 似乎是问题所在。

标签: apache-spark pyspark apache-spark-sql pyspark-sql databricks


【解决方案1】:

回答问题

Spark SQL 计数不正确或者我不能正确编写 SQL?

来自标题:不能正确写SQL。

编写 SQL 的规则:想想NULLUNDEFINED

%sql
SELECT count(*)
FROM (
  SELECT DISTINCT CallType
  FROM fireServiceCalls 
)

34

另外,我显然看不懂:

pault suggested in a comment

只有 30 个值,您可以对所有不同的项目进行排序和打印,以查看差异在哪里。

嗯,其实我自己也是这么想的。 (减去排序。)除了没有任何区别,输出中总是有 34 种调用类型,无论我是使用 SQL 还是 DataFrame 查询生成的。我只是没有注意到其中一个被不祥地命名为null

+--------------------------------------------+
|CallType                                    |
+--------------------------------------------+
|Elevator / Escalator Rescue                 |
|Marine Fire                                 |
|Aircraft Emergency                          |
|Confined Space / Structure Collapse         |
|Administrative                              |
|Alarms                                      |
|Odor (Strange / Unknown)                    |
|Lightning Strike (Investigation)            |
|null                                        |
|Citizen Assist / Service Call               |
|HazMat                                      |
|Watercraft in Distress                      |
|Explosion                                   |
|Oil Spill                                   |
|Vehicle Fire                                |
|Suspicious Package                          |
|Train / Rail Fire                           |
|Extrication / Entrapped (Machinery, Vehicle)|
|Other                                       |
|Transfer                                    |
|Outside Fire                                |
|Traffic Collision                           |
|Assist Police                               |
|Gas Leak (Natural and LP Gases)             |
|Water Rescue                                |
|Electrical Hazard                           |
|High Angle Rescue                           |
|Structure Fire                              |
|Industrial Accidents                        |
|Medical Incident                            |
|Mutual Aid / Assist Outside Agency          |
|Fuel Spill                                  |
|Smoke Investigation (Outside)               |
|Train / Rail Incident                       |
+--------------------------------------------+

【讨论】:

  • 从第一天就开始教人们有关脏数据的知识总是很好。不过,有趣的是与 DF 的区别;可能需要先在那里进行过滤
  • 对我来说,DataFrame 的行为比 SQL 的要直观得多。当然,NULL 是一个相当特殊的(非)值,但为什么不应该将它视为另一个不同的值呢?但是,是的,如果您想在没有 NULL 的情况下进行计数,您可以通过注入删除 NULL 条目的.filter(...) 轻松做到这一点。
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
相关资源
最近更新 更多