使用Spark 2.1(在Databricks上),我有一个表,其中包含一个String类型的列,作为从.CSV文件导入的结果。在针对该表的SELECT查询中,我试图在数学运算中使用列值之前将该列的值转换为整数。我无法找到正确的Spark SQL“功能”来执行此操作。
以下是SQL的示例。 “TO_NUMBER”不适用于两个字符串中的任何一个; Sum_GN_POP或Count1:
SELECT name AS geohashPrefix3, TO_NUMBER(Sum_GN_POP) AS totalPopulation, TO_NUMBER(Count1) AS landMass
FROM wayne_geohash3
WHERE (LENGTH(name) = 3)
如果我能找到相关的文档,那将会很有帮助。我也希望与其他类型进行其他类型的转换(或演员表)。非常感谢任何关于其中一项或两项的指导。
答案 0 :(得分:7)
您可以使用 inferSchema 选项从Integer
文件获取csv
,如下所示:
val df = spark.read.option("inferSchema", true).csv("file-location")
话虽如此:inferSchema选项有时会出错并将类型设为String
。如果是这样,您可以使用cast
Column
运算符
数据框/数据集实施:
val df2 = df.withColumn("Count1", $"Count1" cast "Int" as "landMass").withColumn("Count1", $"Sum_GN_POP" cast "Int" as "totalPopulation")
SQL实施:
SELECT name AS geohashPrefix3, CAST(Sum_GN_POP as INT) AS totalPopulation, CAST(Count1 AS INT) AS landMass
FROM wayne_geohash3
WHERE (LENGTH(name) = 3)
答案 1 :(得分:2)
<强>要点:强>
Apache Spark's SQL与Apache Hive部分兼容。因此,大多数可以在Hive中编写的SQL都可以用Spark SQL编写。
<强>详情:强>
要将STRING转换为特定的数字类型(如INT),可以使用强制转换。演员表包括用括号包裹目标,并在括号前面加上要更改的类型。例如,演员表可能如下所示:
INT(someStringValue)
因此,要使原始发布的问题中的SQL工作,需要将其更改为这样(将名为“TO_NUMBER”的原始函数替换为“INT”):
SELECT name AS geohashPrefix3, INT(Sum_GN_POP) AS totalPopulation, INT(Count1) AS landMass
FROM wayne_geohash3
WHERE (LENGTH(name) = 3)
答案 2 :(得分:2)
我想使用UDF,因为Spark的强制转换不会捕获变量溢出:
val parseInt = udf((s:String) => scala.util.Try{Some(s.toInt)}.getOrElse(None))
Seq("100", "10000000000", "1x0")
.toDF("i")
.select(
$"i" cast "int" as "casted_result",
parseInt($"i") as "udf_result"
).show
+-------------+----------+
|casted_result|udf_result|
+-------------+----------+
| 100| 100|
| 1410065408| null|
| null| null|
+-------------+----------+
答案 3 :(得分:0)
Haroun关于在Sql中进行强制转换的答案对我有用。但是注意,如果字符串中的数字大于integer
,结果将为null
。对于大于integer
(long
或bigint
)的数字,强制类型转换应为:
CAST(Sum_GN_POP as BIGINT)