Обратите внимание, что я не спрашиваю, как сделать то, что может array_contains
, но мне любопытно, есть ли способ использовать in
или isin
для того же. Думаю, выход есть, но думать ясно уже поздно.
Есть ли способ использовать предикат in
SQL или оператор столбца isin
со списком для сопоставления, который поступает со значениями из столбца?
Скажем, у меня есть следующий набор данных nums
:
scala> nums.printSchema
root
|-- id: integer (nullable = false)
|-- nums: array (nullable = true)
| |-- element: integer (containsNull = false)
scala> nums.show
+---+---------+
| id| nums|
+---+---------+
| 1|[1, 2, 3]|
+---+---------+
Я хотел бы написать запрос для использования предиката in
/ isin
с использованием столбцов id
и nums
.
nums.where($"id" isin $"nums")
не работает из-за несоответствия типов:
scala> nums.where($"id" isin $"nums").show
org.apache.spark.sql.AnalysisException: cannot resolve '(`id` IN (`nums`))' due to data type mismatch: Arguments must be same type but were: int != array<int>;;
'Filter id#18 IN (nums#19)
+- AnalysisBarrier
+- Project [_1#15 AS id#18, _2#16 AS nums#19]
+- LocalRelation [_1#15, _2#16]
Доступны ли они в последней версии Spark SQL 2.3? Если нет, то они мне не подходят.
И аналогично в Scala Как использовать значение столбца типа массива в операторе CASE
Пожалуйста, подумайте еще раз, когда вы голосуете, чтобы закрыть вопрос, предлагая использовать array_contains
. Мне интересно, какие функции in
/ isin
отсутствуют, чтобы соответствовать array_contains
, если таковые имеются.
Если вы хотите снова открыть это, я хочу выступить против (вы все равно можете сделать это в одиночку, верно?), Но я не думаю, что здесь действительно есть вопрос, поэтому я не буду делать это сам. Вы уже проанализировали API и пришли к выводу, что он не поддерживается. Лично я не припомню ни одной системы, поддерживающей IN collection
(у Oracle есть x member of array
, у PostgreSQL есть x = ANY(array)
), так что, возможно, это вопрос соответствия стандарту или просто мы делаем это так, потому что все делают.
Согласно документации expression that is evaluated to true if the value of this expression is contained by the **evaluated** values of the arguments.
В исходном коде вы можете ясно видеть, что isin - это метод varargs, а параметр преобразован либо в List, либо в Set. Поэтому без сбора не обойтись.
Спасибо @ user6910411 @addmeaning за вашу помощь. Я наконец «обнаружил», что даже nums.filter("id in (select nums from numsT)").show
не принесет никакой пользы, и я поправился. Простите за шум.
Подходит ли предикат
filter
вашим потребностям? databricks.com/blog/2017/05/24/…