零語義
適用於:磚的SQL磚運行時
表由一組行組成,每行包含一組列。列與數據類型相關聯,並表示實體的特定屬性(例如,年齡
實體的列是否被稱為人
).有時,特定於行的列的值在行出現時還不知道。在SQL
,這些值表示為零
。的語義零
在各種操作符、表達式和其他中的值處理SQL
構造。
下麵說明了名為的表的模式布局和數據人
。數據包含零
中的值年齡
列和此表將在下麵的小節中的各種示例中使用。
Id的名字年齡---------------One hundred.喬30.200結婚零300邁克18400弗雷德50500艾伯特零600米歇爾30.700丹50
比較運算符
Databricks支持標準比較運算符,例如>
,> =
,=
,<
而且< =
。這些操作符的結果未知或零
當一個操作數或兩個操作數未知或零
。為了比較零
, Databricks提供了一個空安全的相等操作符(< = >
),返回假
當其中一個操作數為零
並返回真正的
當兩個操作數都是零
。下表說明了當一個或兩個操作數為時比較操作符的行為零
:
左操作數 |
右操作數 |
|
|
|
|
|
|
---|---|---|---|---|---|---|---|
零 |
任何價值 |
零 |
零 |
零 |
零 |
零 |
假 |
任何價值 |
零 |
零 |
零 |
零 |
零 |
零 |
假 |
零 |
零 |
零 |
零 |
零 |
零 |
零 |
真正的 |
例子
—當其中一個操作數為' NULL '時,普通比較操作符返回' NULL '。>選擇5>零作為expression_output;expression_output-----------------零——當兩個操作數都為' NULL '時,普通比較操作符返回' NULL '。>選擇零=零作為expression_output;expression_output-----------------零當其中一個操作數為“NULL”時,返回“False”>選擇5< = >零作為expression_output;expression_output-----------------假當其中一個操作數為“NULL”時,返回“True”>選擇零< = >零;expression_output-----------------真正的-----------------
邏輯運算符
Databricks支持標準邏輯運算符,例如和
,或
而且不
。這些運算符取布爾
表達式作為參數,並返回a布爾
價值。
下表說明了當一個或兩個操作數為時邏輯運算符的行為零
。
左操作數 |
右操作數 |
或 |
和 |
---|---|---|---|
真正的 |
零 |
真正的 |
零 |
假 |
零 |
零 |
假 |
零 |
真正的 |
真正的 |
零 |
零 |
假 |
零 |
假 |
零 |
零 |
零 |
零 |
操作數 |
不 |
---|---|
零 |
零 |
例子
—當其中一個操作數為' NULL '時,普通比較操作符返回' NULL '。>選擇(真正的或零)作為expression_output;expression_output-----------------真正的——當兩個操作數都為' NULL '時,普通比較操作符返回' NULL '。>選擇(零或假)作為expression_outputexpression_output-----------------零——當其中一個操作數為“NULL”時,空安全的相等運算符返回“False”>選擇不(零)作為expression_output;expression_output-----------------零
表達式
比較運算符和邏輯運算符在Databricks中被視為表達式。Databricks還支持其他形式的表達式,可以大致分為:
零不容忍表達式
可以處理的表達式
零
值操作數這些表達式的結果取決於表達式本身。
可以處理空值操作數的表達式
這類表達式被設計用來處理零
值。表達式的結果取決於表達式本身。以函數表達式為例isnull
返回一個真正的
在空輸入和假
對於非空輸入,其中作為函數合並
返回第一個非零
值在操作數列表中的值。然而,合並
返回零
當它的所有操作數為零
。下麵是這類表達式的不完整列表。
合並
NULLIF
IFNULL
NVL
NVL2
ISNAN
NANVL
ISNULL
ISNOTNULL
ATLEASTNNONNULLS
在
例子
>選擇isnull(零)作為expression_output;expression_output-----------------真正的——返回第一次出現的非“NULL”值。>選擇合並(零,零,3.,零)作為expression_output;expression_output-----------------3.——返回' NULL ',因為它所有的操作數都是' NULL '。>選擇合並(零,零,零,零)作為expression_output;expression_output-----------------零>選擇isnan(零)作為expression_output;expression_output-----------------假
內置聚合表達式
聚合函數通過處理一組輸入行來計算單個結果。下麵是如何做的規則零
值由聚合函數處理。
零
所有聚合函數在處理過程中都會忽略值。該規則的唯一例外是COUNT(*)函數。
一些聚合函數返回
零
當所有輸入值為零
或者輸入數據集為空。這些函數的列表是:馬克斯
最小值
總和
AVG
每一個
任何
一些
例子
——' count(*) '不跳過' NULL '值。>選擇數(*)從人;數(1)--------7——列' age '中的' NULL '值將從處理中跳過。>選擇數(年齡)從人;數(年齡)----------5——' count(*) '在空輸入集上返回0。這是不一樣的——聚合函數,如' max ',返回' NULL '。>選擇數(*)從人在哪裏1=0;數(1)--------0—“NULL”值不包括在最大值的計算中。>選擇馬克斯(年齡)從人;馬克斯(年齡)--------50——' max '在空輸入集上返回' NULL '。>選擇馬克斯(年齡)從人在哪裏1=0;馬克斯(年齡)--------零
中的條件表達式在哪裏
,有
,加入
條款
在哪裏
,有
操作符根據用戶指定的條件篩選行。一個加入
運算符用於根據連接條件組合來自兩個表的行。對於這三個操作符,條件表達式是一個布爾表達式,可以返回真正的
,假
或未知的(空)
。如果條件的結果是“滿意的”真正的
。
例子
年齡未知(' NULL ')的人從結果集中過濾出來。>選擇*從人在哪裏年齡>0;的名字年齡-------- ---米歇爾30.弗雷德50邁克18丹50喬30.——“IS NULL”表達式在析取中用於選擇人物—未知(' NULL ')記錄。>選擇*從人在哪裏年齡>0或年齡是零;的名字年齡-------- ----艾伯特零米歇爾30.弗雷德50邁克18丹50結婚零喬30.年齡未知(“NULL”)的人員將跳過處理。>選擇*從人集團通過年齡有馬克斯(年齡)>18;年齡數(1)--- --------50230.2——一個連接條件為' p1 '的自連接案例。年齡= p2。年齡和p1.的名字=p2.的名字`.年齡未知(' NULL ')的人被join操作符過濾掉。>選擇*從人p1,人p2在哪裏p1。年齡=p2。年齡和p1。的名字=p2。的名字;的名字年齡的名字年齡-------- --- -------- ---米歇爾30.米歇爾30.弗雷德50弗雷德50邁克18邁克18丹50丹50喬30.喬30.——使用null-safe equals來比較來自join的兩個分支的age列——這就是為什麼年齡未知(' NULL ')的人被join限定的原因。>選擇*從人p1,人p2在哪裏p1。年齡< = >p2。年齡和p1。的名字=p2。的名字;的名字年齡的名字年齡-------- ---- -------- ----艾伯特零艾伯特零米歇爾30.米歇爾30.弗雷德50弗雷德50邁克18邁克18丹50丹50結婚零結婚零喬30.喬30.
聚合運算符(集團通過
,截然不同的
)
如在比較運算符,兩個零
價值觀是不相等的。但是,出於分組和區別處理的目的,兩個或多個值配合零數據
都被分組到同一個桶中。此行為符合SQL標準和其他企業數據庫管理係統。
排序運算符(訂單通過
條款)
Databricks支持空排序規範訂單通過
條款。Databricks處理訂單通過
子句通過放置所有的零
值的初始值或最後值,具體取決於空排序規範。默認情況下,所有的零
價值觀放在第一位。
例子
首先顯示“NULL”值和其他值——按升序排序。>選擇年齡,的名字從人訂單通過年齡;年齡的名字---- --------零結婚零艾伯特18邁克30.米歇爾30.喬50弗雷德50丹——除' NULL '以外的列值按升序排序——way和' NULL '值顯示在最後。>選擇年齡,的名字從人訂單通過年齡零位最後的;年齡的名字---- --------18邁克30.米歇爾30.喬50丹50弗雷德零結婚零艾伯特——除' NULL '值外的列按降序排序-和' NULL '值顯示在最後。>選擇年齡,的名字從人訂單通過年齡DESC零位最後的;年齡的名字---- --------50弗雷德50丹30.米歇爾30.喬18邁克零結婚零艾伯特
集合運算符(聯盟
,相交
,除了
)
零
在set操作的上下文中,以空安全的方式比較值是否相等。這意味著當比較行時,是2零
不同於常規的值被認為是相等的等於
(=
)算子。
例子
>創建視圖unknown_age作為選擇*從人在哪裏年齡是零;-隻有“機密數據庫”兩段之間的普通行在——結果集。行中的列之間的比較已經完成—以零安全的方式。>選擇的名字,年齡從人相交選擇的名字,年齡從unknown_age;的名字年齡------ ----艾伯特零結婚零——來自' EXCEPT '的兩個分支的' NULL '值不在輸出中。這基本上表明比較是以零安全的方式進行的。>選擇年齡,的名字從人除了選擇年齡從unknown_age;年齡的名字--- --------30.喬50弗雷德30.米歇爾18邁克50丹——在兩組數據之間執行“UNION”操作。行中各列之間的比較已完成——零安全方式。>選擇的名字,年齡從人聯盟選擇的名字,年齡從unknown_age;的名字年齡-------- ----艾伯特零喬30.米歇爾30.結婚零弗雷德50邁克18丹50
存在
而且不存在
子查詢
在磚,存在
而且不存在
表達式被允許在在哪裏
條款。這些是返回任意一個的布爾表達式真正的
或假
。換句話說,存在
是會員條件和回報嗎真正的
當它引用的子查詢返回一行或多行。類似地,NOT EXISTS是非成員條件並返回真正的
當子查詢不返回行或零返回行時。
這兩個表達式不受子查詢結果中NULL的影響。它們通常更快,因為它們可以轉換為半連接和反猶太連接,而不需要為空感知提供特殊規定。
例子
—即使子查詢生成了帶有' NULL '值的行,' EXISTS '表達式——當子查詢生成1行時,求值為' TRUE '。>選擇*從人在哪裏存在(選擇零);的名字年齡-------- ----艾伯特零米歇爾30.弗雷德50邁克18丹50結婚零喬30.——“NOT EXISTS”表達式返回“FALSE”。它隻在——subquery不生成任何行。在本例中,它返回1行。>選擇*從人在哪裏不存在(選擇零);的名字年齡---- ---——“NOT EXISTS”表達式返回“TRUE”。>選擇*從人在哪裏不存在(選擇1在哪裏1=0);的名字年齡-------- ----艾伯特零米歇爾30.弗雷德50邁克18丹50結婚零喬30.
在
而且不在
子查詢
在磚,在
而且不在
表達式被允許在在哪裏
子句。不像存在
表達式,在
表達式可以返回真正的
,假
或未知的(空)
價值。從概念上講一個在
表達式在語義上等價於一組由析取操作符(或
).例如,c1 IN(1,2,3)在語義上等價於(C1=1或c1=2或c1=3)
。
至於處理零
值是有關的,語義可以從零
比較運算符中的值處理(=
)和邏輯運算符(或
).總之,下麵是計算an結果的規則在
表達式。
真正的
當在列表中找到非null值時返回假
當列表中沒有非NULL值且列表不包含NULL值時返回未知的
當值為零
,或者在列表中找不到非null值,且列表中至少包含一個零
價值
不在
當列表包含時總是返回UNKNOWN零
,與輸入值無關。這是因為在
返回未知的
如果該值不在包含零
,因為不未知的
再一次未知的
。
例子
—子查詢在結果集中隻有' NULL '值。因此,——' IN '謂詞的結果是UNKNOWN。>選擇*從人在哪裏年齡在(選擇零);的名字年齡---- ---——子查詢在結果集中有' NULL '值以及一個有效的——值“50”。返回年齡= 50的行。>選擇*從人在哪裏年齡在(選擇年齡從值(50),(零)子(年齡));的名字年齡---- ---弗雷德50丹50——由於子查詢在結果集中有' NULL '值,' NOT in '——predicate將返回UNKNOWN。因此,沒有行——符合此查詢的條件。>選擇*從人在哪裏年齡不在(選擇年齡從值(50),(零)子(年齡));的名字年齡---- ---