Как использовать дату (как строку) в структурированном запросе? - PullRequest
0 голосов
/ 20 января 2020

Как программно вычесть дни из даты в искре sql?

val date = "2019-10-01"

val tmp = spark.sql(""" 
select id, 
count(distinct purchase_id) as count_purchases
from
my_table
where partition_date between ('$date'-6) and '$date'
group by 1
""")

пробовал:

val tmp = spark.sql(""" 
select id, 
count(distinct purchase_id) as count_purchases
from
my_table
where partition_date between CAST(CAST('$date' as DATE) - interval '6' day) as varchar) and '$date'
group by 1
""")

получает ошибку: parser exception at varchar

Также попробовал

val tmp = spark.sql(""" 
select id, 
count(distinct purchase_id) as count_purchases
from
my_table
where partition_date between sub_date('$date',6) and 
'$date'
group by 1
""")

Ответы [ 3 ]

1 голос
/ 20 января 2020

Вы можете достичь этого с помощью чистого scala:

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

val someDateStr = "2020-01-20 00:00:00"
val endDate = LocalDateTime.parse(someDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
val startDate = endDate.minusDays(6)

startDate

. Это выведет startDate: java.time.LocalDateTime = 2020-01-14T00:00, тогда вы можете использовать startDate и endDate в своем запросе с интерполяцией строк:

val tmp = s"""select id, count(distinct purchase_id) as count_purchases 
          from my_table 
          where partition_date between 
CAST('${startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))}' AS DATE) and 
CAST('${endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))}' AS DATE) 
          group by 1"""

В качестве альтернативы вы можете использовать встроенную функцию date_sub вместе с CAST:

val endDate = "2020-01-20"

val query = s"""select id, count(distinct purchase_id) as count_purchases 
          from my_table 
          where partition_date between date_sub(CAST('$endDate' AS DATE), 6) and CAST('$endDate' AS DATE)
          group by 1"""

spark.sql(query)
0 голосов
/ 22 января 2020

Что-то, что я бы посчитал более идиоматическим c Код Spark выглядел бы следующим образом:

val date = "2019-10-01"
val q = spark.range(1).select(date_format(lit(date), "yyyy-MM-dd") as "end_date")
scala> q.show
+----------+
|  end_date|
+----------+
|2019-10-01|
+----------+

С этим и функцией date_add SQL вы можете использовать это в SQL запрос:

val q = sql("""
  select date_add(date_format('2019-10-01', "yyyy-MM-dd"), -6) as start_date
  """)
scala> q.show
+----------+
|start_date|
+----------+
|2019-09-25|
+----------+
0 голосов
/ 20 января 2020

Взгляните на этот ответ.

Используйте функцию expr (если у вас есть значения Dynami c от столбцов до вычитания):

из pyspark. sql .functions import * df.withColumn ('substracted_dates', expr ("date_sub (date_col, days_col)")) Используйте функцию withColumn (если у вас есть литеральные значения для вычитания) :

df.withColumn ('substracted_dates', date_sub ('date_col',))

...