Поведение окна Spark SQL по порядку - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть простая таблица с 3 столбцами, depName, empNo, salary, когда я запускаю следующий запрос окна

val ws = Window.partitionBy("depName").orderBy("empNo")

ds.withColumn("avg", avg("salary") over ws).show()

, он выводит следующий результат, он показывает, что оклад avg в пределах depName отпервый ряд к текущему.Как такое могло произойти?Я думал, что все avg с одним deptName должны быть одинаковыми.

Если я не использую orderBy("empNo") для создания ws, то все avg с одним deptName одинаковы.

Я бы спросил, как это происходит, спасибо.

 +---------+-----+------+-----------------+
|  depName|empNo|salary|              avg|
+---------+-----+------+-----------------+
|  develop|    7|  4200|           4200.0|
|  develop|    8|  6000|           5100.0|
|  develop|    9|  4500|           4900.0|
|  develop|   10|  5200|           4975.0|
|  develop|   11|  5200|           5020.0|
|    sales|    1|  5000|           5000.0|
|    sales|    3|  4800|           4900.0|
|    sales|    4|  4800|4866.666666666667|
|personnel|    2|  3900|           3900.0|
|personnel|    5|  3500|           3700.0|
+---------+-----+------+-----------------+

Ответы [ 2 ]

3 голосов
/ 04 апреля 2019

Функция окна AVG() работает со строками, определенными в окне, и возвращает значение для каждой строки. Запрос с AVG() возвращает одну строку со средним значением всех значений в указанном столбце вместо возврата значений для каждой строки.

Предложение PARTITION BY подразделяет окно на разделы. Предложение ORDER BY определяет логический порядок строк в каждом разделе результирующего набора. Оконные функции применяются к каждой строке, как и когда она возвращается после упорядочения в каждом разделе. Вот почему он возвращает скользящее среднее, а не общее среднее.

Согласно документации github,

  • @ note Если порядок не определен, по умолчанию используется неограниченная оконная рамка (rowFrame, unboundedPreceding, unboundedFollowing). Когда порядок определен, по умолчанию используется растущая оконная рама (rangeFrame, unboundedPreceding, currentRow).

https://github.com/apache/spark/blob/1d95dea30788b9f64c5e304d908b85936aafb238/sql/core/src/main/scala/org/apache/spark/sql/expressions/Window.scala#L36

0 голосов
/ 04 апреля 2019

Можете ли вы попробовать с приведенным ниже синтаксисом.Это будет работать так, как вы ожидали, так как найдет среднее значение путем разбиения в соответствии с depName и порядком empNo

df.withColumn("avg_Time", avg($"salary").over(Window.partitionBy($"depName"))).orderBy("empNo").show()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...