PySpark 2.3.0脚本客户端模式执行返回0结果问题求助
问题解决:PySpark SQL查询无法识别日期变量导致结果为0
我一眼就看出问题出在哪了——你在拼接SQL字符串的时候,日期变量没有用单引号包裹!Spark会把2020-03-01当成一个数学表达式(2020减3减1等于2016),而不是你想要的日期字符串,这样查询条件完全不对,自然返回0条结果。
给你几个靠谱的解决办法:
1. 直接给变量加上单引号(最直接)
修改SQL拼接的代码,在{}外面加上单引号,确保生成的SQL里日期是字符串常量:
df = sqlContext.sql("select * from db.table where cast(inserted_timestamp as string) >= '{}' and cast(inserted_timestamp as string) < '{}'".format(yesterday,today))
这样生成的SQL就会是>= '2020-03-01',符合SQL的语法要求,能正确匹配数据。
2. 用参数化查询(更安全,避免SQL注入)
如果你担心字符串拼接带来的安全问题,或者变量里有特殊字符,可以用PySpark的参数绑定:
df = sqlContext.sql( "select * from db.table where cast(inserted_timestamp as string) >= ? and cast(inserted_timestamp as string) < ?", (yesterday, today) )
这种方式会自动帮你处理变量的类型和引号,比手动拼接更稳妥。
3. 避免字符串转换,直接用日期类型比较(性能更好)
没必要把inserted_timestamp转成字符串来比较,直接用Spark的日期函数处理,性能会更高:
df = sqlContext.sql("select * from db.table where inserted_timestamp >= to_date('{}') and inserted_timestamp < to_date('{}')".format(yesterday, today))
to_date会把你的日期字符串转成日期类型,和原生的timestamp字段直接比较,既高效又不容易出错。
最后提醒你:可以先打印一下生成的SQL语句(比如print("select * ...".format(...))),看看是不是符合预期,这样能快速排查这类拼接问题。
内容的提问来源于stack exchange,提问作者Alessio Iannini
相关产品推荐
相关产品推荐

