Share via


SQL 資料類型規則

適用于:核取標示為是 Databricks SQL 檢查標示為是 Databricks Runtime

Azure Databricks 會使用數個規則來解決資料類型之間的衝突:

您也可以在許多類型之間明確轉換:

  • 轉換函 式會在大部分類型之間轉換,並在無法時傳回錯誤。
  • try_cast函 式的運作方式類似 cast 函 式,但在傳遞無效值時會傳回 Null。
  • 使用提供的格式指示詞,在型別之間轉換其他內建函式。

類型升級

類型升級是將類型轉換成相同類型系列的另一種類型的程式,其中包含原始類型的所有可能值。 因此,類型升級是安全的作業。 例如 TINYINT ,範圍從 -128127 。 其所有可能的值都可以安全地升階為 INTEGER

類型優先順序清單

類型優先順序清單會定義指定的資料類型值是否可以隱含地升級為另一個資料類型。

資料類型 優先順序清單 (範圍從最窄到最寬的)
TINYINT TINYINT - SMALLINT - > INT - >> BIGINT - > DECIMAL - > FLOAT (1) - > DOUBLE
SMALLINT SMALLINT - INT - > BIGINT - >> DECIMAL - > FLOAT (1) - > DOUBLE
Int INT - BIGINT - > DECIMAL - >> FLOAT (1) - > DOUBLE
BIGINT BIGINT - DECIMAL - >> FLOAT (1) - > DOUBLE
十進位 DECIMAL - > FLOAT (1) - > DOUBLE
浮動 FLOAT (1) - > DOUBLE
日期 DATE - > TIMESTAMP
時間 戳 時間 戳
陣 列 ARRAY (2)
二 進 制 二 進 制
布林 布林
區間 區間
地圖 MAP (2)
字串 字串
結構 STRUCT (2)

(1) 針對 最不常見的類型解析 FLOAT,會略過以避免遺失精確度。

(2) 對於複雜類型,優先順序規則會以遞迴方式套用至其元件元素。

字串和 Null

特殊規則適用于 STRING 和 不具 NULL 類型的 :

  • NULL 可以升階為任何其他類型。
  • STRING 可以升階為 BIGINTBINARYBOOLEANDATEDOUBLEINTERVALTIMESTAMP 。 如果實際字串值無法轉換成 最低通用類型 Azure Databricks,就會引發執行階段錯誤。 升級至 INTERVAL 字串值時,必須符合間隔單位。

類型優先順序圖表

這是優先順序階層的圖形描述,結合 類型優先順序清單字串和 Nulls 規則。

優先順序規則的圖形標記法

最不常見的類型解析

一組型別中最不常見的型別是類型優先順序圖表中所有元素都能從 類型優先順序圖表 連線到的最窄型別。

最不常見的類型解析是用來:

  • 決定是否可以使用較窄型別的引數來叫用預期指定型別參數的函式。
  • 衍生函式的引數類型,該函式需要多個參數的共用引數類型,例如 聯合inleastgreatest
  • 針對算數運算或比較等運算子衍生運算元類型。
  • 衍生案例 運算式等運算式的結果類型。
  • 衍生 陣列對應 建構函式的專案、索引鍵或實值型別。
  • 衍生 UNION、INTERSECT 或 EXCEPT set 運算子的結果類型。

如果最通用的類型解析為 FLOAT ,則會套用特殊規則。 如果任何參與型別是確切的數數值型別, (TINYINTSMALLINTINTEGERBIGINTDECIMAL) 會推送最不常見的類型, DOUBLE 以避免遺失數位。

隱含下播和跨播

Azure Databricks 只會在函式和運算子叫用上採用這些形式的隱含轉型,而且只有在可以明確判斷意圖的位置。

  • 隱含下播

    隱含向下傳播會自動將較寬的類型轉換成較窄的類型,而不需要明確指定轉換。 向下傳播很方便,但如果實際值無法在窄型別中表示,則會有非預期執行時間錯誤的風險。

    向下傳播會以反向順序套用 類型優先順序清單

  • 隱含跨播

    隱含交叉傳播會將某個類型系列的值轉換成另一個類型系列,而不需要明確指定轉換。

    Azure Databricks 支援下列來源的隱含交叉傳送:

    • 除了 以外的 BINARY 任何簡單型別,到 STRING 除外。
    • STRING任何簡單類型的 。

在函式調用上轉型

假設有已解析的函式或運算子,下列規則會依每個參數和引數組的順序套用:

  • 如果支援的參數類型屬於引數 的類型優先順序圖表,Azure Databricks 會將引數 階為該參數類型。

    在大部分情況下,函式描述會明確指出支援的型別或鏈結,例如「任何數數值型別」。

    例如, sin (expr) 運作 DOUBLE ,但會接受任何數值。

  • 如果預期的參數類型為 , STRING 且引數為簡單類型 Azure Databricks 會將引數 交叉傳送 至字串參數類型。

    例如, 子字串 (str、start、len) 預期 strSTRING 。 相反地,您可以傳遞數值或日期時間類型。

  • 如果引數類型為 , STRING 且預期的參數類型為簡單型別,Azure Databricks 會將字串引數 交叉傳送 至最廣泛的支援參數類型。

    例如, date_add (日期、) 預期 DATE 為 和 INTEGER

    如果您使用兩 STRING 個 s 來叫 date_add() 用,Azure Databricks 會將第一個 STRING 交叉傳送至 DATE ,而第二 STRINGINTEGER 會交叉傳送至 。

  • 如果函式需要數數值型別,例如 INTEGERDATE 型別,但引數是較通用的類型,例如 DOUBLETIMESTAMP ,則 Azure Databricks 會隱含 地將引數向下傳播 至該參數類型。

    例如, date_add (日期、) 預期 DATE 為 和 INTEGER 的天數。

    如果您使用 和 BIGINTdate_add()TIMESTAMP ,Azure Databricks 會藉由移除時間元件和 , BIGINT 將 向下傳播TIMESTAMPDATEINTEGER

  • 否則,Azure Databricks 會引發錯誤。

例子

只要聯合函式共用最不通用的類型,聯合函式就會接受任何一組引數類型。

結果類型是引數的最低常見類型。

-- The least common type of TINYINT and BIGINT is BIGINT
> SELECT typeof(coalesce(1Y, 1L, NULL));
  BIGINT

-- INTEGER and DATE do not share a precedence chain or support crosscasting in either direction.
> SELECT typeof(coalesce(1, DATE'2020-01-01'));
Error: Incompatible types [INT, DATE]

-- Both are ARRAYs and the elements have a least common type
> SELECT typeof(coalesce(ARRAY(1Y), ARRAY(1L)))
  ARRAY<BIGINT>

-- The least common type of INT and FLOAT is DOUBLE
> SELECT typeof(coalesce(1, 1F))
  DOUBLE

> SELECT typeof(coalesce(1L, 1F))
  DOUBLE

> SELECT typeof(coalesce(1BD, 1F))
  DOUBLE

-- The least common type between an INT and STRING is BIGINT
> SELECT typeof(coalesce(5, '6'));
  BIGINT

-- The least common type is a BIGINT, but the value is not BIGINT.
> SELECT coalesce('6.1', 5);
  Error: 6.1 is not a BIGINT

-- The least common type between a DECIMAL and a STRING is a DOUBLE
>  SELECT typeof(coalesce(1BD, '6'));
  DOUBLE

子字串函式預期字串的類型 STRING 引數,以及 INTEGER 開始和長度參數的引數。

-- Promotion of TINYINT to INTEGER
> SELECT substring('hello', 1Y, 2);
 he

-- No casting
> SELECT substring('hello', 1, 2);
 he

-- Casting of a literal string
> SELECT substring('hello', '1', 2);
 he

-- Downcasting of a BIGINT to an INT
> SELECT substring('hello', 1L, 2);
 he

-- Crosscasting from STRING to INTEGER
> SELECT substring('hello', str, 2)
  FROM VALUES(CAST('1' AS STRING)) AS T(str);
 he

-- Crosscasting from INTEGER to STRING
> SELECT substring(12345, 2, 2);
 23

|| (CONCAT) 允許隱含交叉傳送至字串。

-- A numeric is cast to STRING
> SELECT 'This is a numeric: ' || 5.4E10;
 This is a numeric: 5.4E10

-- A date is cast to STRING
> SELECT 'This is a date: ' || DATE'2021-11-30';
 This is a date: 2021-11-30

date_add可以使用 或 BIGINT 叫用 TIMESTAMP ,因為隱含的下播。

> SELECT date_add(TIMESTAMP'2011-11-30 08:30:00', 5L);
 2011-12-05

date_add 可以透過 叫用 , STRING 因為隱含的交叉傳送。

> SELECT date_add('2011-11-30 08:30:00', '5');
  2011-12-05