Spark SQL (блоки данных) - AnalysisException: не удается оценить выражение external () в определении встроенной таблицы - агрегат из нескольких столбцов - PullRequest
0 голосов
/ 18 января 2020

Я перехожу на (Azure) Databricks 6.2 (включая Apache Spark 2.4.4, Scala 2.11) из некоторых реальных реляционных баз данных. Для него я использую только Spark SQL.

Поскольку MIN является агрегатной функцией, а получение MIN для нескольких значений (столбцов, а не строк) затруднительно, я использовал конструктор VALUES Row для создания встроенных подзапросов и использовал агрегатную функцию MIN над этим подзапросом для создания простых операторов.

конструктор VALUE ROW работает нормально

select min(MinLatency) from (VALUES(1), (2), (3), (4), (5), (6), (7), (8)) MINL(MinLatency)

как для этого запроса (дополнительный вопрос, почему я не могу написать min (MINL.MinLatency) - но это не проблема)

Также как подзапрос работает

select 
  Latency,
  (select sum(C1) from (VALUES(1), (2), (3), (4), (5), (6), (7), (8)) Y(C1)) as C 
from 
  (VALUES(1), (2), (3), (4), (5), (6), (7), (8)) as X(Latency)

Но, выполняя реальный запрос (упрощенно с константами только для этого примера)

select 
  T1.ID,
  --min of 4 Values
  T1.C1, T2.C2, T3.C3, T4.C4,
  --(select min(Value) from (VALUES(1),(2),(3),(4)) TI(Value)) as MIN
  (select min(Value) from (VALUES(T1.C1),(T2.C2),(T3.C3),(T4.C4)) TI(Value)) as MIN
from 
  (select 1 as ID, 1 as C1 union all select 2 as ID, 1 as C1) T1
  inner join (select 1 as ID, 2 as C2 union all select 2 as ID, 2 as C2) T2 on T1.ID=T2.ID
  inner join (select 1 as ID, 3 as C3 union all select 2 as ID, 3 as C3) T3 on T1.ID=T3.ID
  inner join (select 1 as ID, 4 as C4 union all select 2 as ID, 4 as C4) T4 on T1.ID=T4.ID 

Databricks / Spark возвращает ошибку

Ошибка в операторе SQL: AnalysisException: невозможно оценить выражение external () в определении встроенной таблицы; строка 6 поз. 34

Если вы попробуете это с константами, то оно работает.

Вопросы действительно,

  • что я делаю неправильно?
  • это действительно не поддерживается? Почему?
  • как мне сделать многоколонку MIN такой же простой, как в Spark SQL? (как min игнорирует значения NULL)

Помощь приветствуется

Спасибо

1 Ответ

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

Если предположить, что значения никогда не равны NULL, самое простое решение - LEAST():

select T1.ID,
       --min of 4 Values
       T1.C1, T2.C2, T3.C3, T4.C4,
       least(T1.C1, T2.C2, T3.C3, T4.C4)
. . . 

Вы также можете сделать это, используя вид сбоку. Упрощенный пример будет:

select t1.id, min(c)
from t1 lateral view
     explode(array(c1, c2, c3, c4)) c
group by t1.id;
...