取消
顯示的結果
而不是尋找
你的意思是:

列相關異常在SQL UDF使用UDF時參數。

Johan_Van_Noten
新的貢獻者三世

環境

Azure磚10.1,包括3.2.0火花

場景

我想要檢索的平均兩個時間戳之間的一係列的值,使用一個SQL UDF。

平均顯然隻是一個例子。在真實的場景中,我想隱藏一些額外的查詢SQL UDF背後的複雜性。

試(工作)

% sql SELECT avg(溫度)從oventemperatures averageTemperature ovenTimestamp to_timestamp之間(“1999-01-01”)和to_timestamp (“2021-12-31”)

這可能在一個UDF。

創建函數averageTemperatureUDF (ovenID字符串,開始時間的時間戳,endTime時間戳)返回讀取SQL數據浮動SQL安全定義者返回選擇avg (ovenTemperature)從oventemperatures averageTemperature ovenTimestamp to_timestamp之間(“1999-01-01”)和to_timestamp (“2021-12-31”)

試(失敗)

當我想使用UDF的過濾條件參數,函數定義失敗。

創建函數averageTemperatureUDF (ovenID字符串,開始時間的時間戳,endTime時間戳)返回讀取SQL數據浮動SQL安全定義者返回選擇avg (ovenTemperature)從oventemperatures averageTemperature ovenTimestamp開始時間和endTime之間

錯誤消息抱怨“相關列”。

錯誤的SQL語句:AnalysisException:相關列是不允許謂詞(spark_catalog.default.oventemperatures.ovenTimestamp > =外(averageTemperatureUDF.startTime)) (spark_catalog.default.oventemperatures.ovenTimestamp < =外(averageTemperatureUDF.endTime)):總(avg (ovenTemperature # 275) averageTemperature # 9299) + -過濾器((ovenTimestamp # 273 > =外(開始時間# 9301))和(ovenTimestamp # 273 < =外(endTime # 9302))) + - SubqueryAlias spark_catalog.default.oventemperatures + -關係default.oventemperatures [ovenTimestamp # 273, (…), ovenTemperature # 275, (……)] JDBCRelation (OvenTemperatures) (numPartitions = 1)

問題(s)

似乎不接受使用UDF的內參數表達式。

  • 這是一個正確的結論嗎?
  • 這種限製的理由嗎?
  • 替代解決這個嗎?
19日回複19

Johan_Van_Noten
新的貢獻者三世

嗨羅伯特,

謝謝你的建議。我想做這個在SparkSQL是因為沒有底層。狀態"置疑"可能會有,但通常沒有。我們利用的可能性SparkSQL抽象底層數據存儲(檢查機關文件、CSV文件或SQL數據)到一個SQL-alike層。這是一種虛擬管理。

在這種情況下,我沒有看到一個選項來代表較低的SQL server的UDF。我忽略的東西嗎?

最好的問候,

約翰

Raghu_Bindingan
新的貢獻者三世

嗨@Johan Van Noten,

你能解決這個問題。UDF不介意一個等價的運營商,但不喜歡它當謂詞>或<非等價算子。

嗨@Raghu Bindinganavale,

我無法解決這個認為這SparkSQL的限製。我們現在處理它在更高的層,這是不幸的。

謝謝,

約翰

嗨@Johan Van Noten

我明白了,這是一個非常不同的SQL那麼我習慣但它的作品,你可以試試下麵並調整您的需求。基本上火花sql不喜歡不等於謂詞,那麼您將需要使用一個自我加入到同一個表並創建一個列,相當於你的條件,然後加入,回到你的主要表來獲得期望的結果。不同於我們日常的SQL:grinning_face:

創建函數

averageTemperatureUDF (ovenID字符串,開始時間的時間戳,endTime時間戳)

返回浮動

讀取SQL SQL數據安全定義者

返回選擇avg (ovenTemperature) averageTemperature

從oventemperatures基地

內連接(選擇ovenTimestamp開始時間和endTime之間的標簽,從oventemperatures ovenTimestamp) * * * * *

在基地。ovenTimestamp = * * * * * .ovenTimestamp

* * * * *。標簽是正確的

嗨@Raghu Bindinganavale,

謝謝你的建議。

我不確定的SQL引擎如何優化這個查詢,但從本質上說,你是計算condition-label所有oventemperatures之後隻在完整的存儲(百萬)和過濾的好的壞的在where子句中。

雖然oventemperatures ovenTimestamp(虛擬)表分區,因此應該能夠解決之間非常的快,我想這你的解決方案可能不會與可接受的性能運行。你認為查詢優化器能夠通過這個有效嗎?

在我的場景描述,我表示,這隻是一個簡化的例子來闡明這個問題。我想雖然在一般情況下,隔離的條件你提出可能的方式。雖然我對性能仍持懷疑態度。我需要嚐試你的建議一旦我有機會重構應用程序。

最好的問候,

約翰

Baidu
map