Oracle與Sqlserver:Order by NULL值介紹

針對頁面傳參到in的子集中去進行查詢操做的話,就會有in(xxx,null),這樣就會致使查詢的結果中其實直接過濾掉了null,根本就查不出來null的值。以前對於null的操做都是進行不一樣數據庫的null函數來進行選擇nvl、isnull、ifnull等,直接將字段的null進行轉換後再操做。sql

只知道要對數據庫中的null進行轉換的操做,可是不知所云,因此今天就大體瞭解下。針對oracle的null的基本操做:數據庫

1、null值的介紹 oracle

NULL 是數據庫中特有的數據類型,當一條記錄的某個列爲 NULL ,則表示這個列的值是未知的、是不肯定的。既然是未知的,就有無數種的可能性。所以, NULL 並非一個肯定的值。 這是 NULL 的由來、也是 NULL的基礎,全部和 NULL 相關的操做的結果均可以從 NULL 的概念推導出來。函數

2、oracle中的null值介紹 sqlserver

在不知道具體有什麼數據的時候,即未知,能夠用NULL, 稱它爲空,ORACLE中,含有空值的表列長度爲零。容許任何一種數據類型的字段爲空,除了如下兩種狀況:性能

a、主鍵字段(primary key);測試

b、定義時已經加了NOT NULL限制條件的字段spa

3、Oracle中null值說明:翻譯

a、等價於沒有任何值、是未知數。設計

b、NULL與0、空字符串、空格都不一樣。

c、對空值作加、減、乘、除等運算操做,結果 仍爲空。

d、NULL的處理使用NVL函數。

e、比較時使用關鍵字用「is null」和「is not null」。

f、空值不能被索引,因此查詢時有些符合條件的數據可能查不出來, count(expr)中,用nvl(列名,0)處理後再查。

g、排序時比其餘數據都大(索引默認是降序排列,小→大), 因此NULL值老是排在最後。

IS NULL 和IS NOT NULL 是不可分割的總體,改成IS 或IS NOT都是錯誤的,從上面咱們看到了NULL 和空字符串的區別。

任何和NULL 的比較操做,如<>、=、<=等都返回UNKNOWN(這裏的unknown就是null,它單獨使用和布爾值false相似).判斷和比較規則總結以下:

 

 

4、null作一些算術運算

好比+,-,*,/等,結果 仍是null,可是對於鏈接操做符||,null忽略,concat函數也忽略null 

5、null相關函數規則 

Oracle有nvl、nvl二、nullif、coalesce等函數專門處理null

nvl(expr1,expr2):若是expr1是null,那麼用expr2做爲返回值,不是null則返回expr1.expr1與expr2通常是類型相同的,若是類型不一樣則會採用自動轉換,轉換失敗則報錯。

nvl2(expr1,expr2,expr3):expr1若是是null,則返回expr3,不然返回expr2,expr2和expr3類型不一樣,expr3類型轉換爲expr2類型

nullif(expr1,expr2):判斷expr1和expr2是否相等,若相等則返回null,不然返回expr1.要求expr1與expr2類型必須相同

coalesce(expr1,expr2,…,exprn):從左到右返回第一個爲非null的值,若全部的列表元素都爲null,則返回null。要求全部都必須爲同一類型。 

6、null與索引 

Oracle中的B*Tree索引,並不存儲全爲null的列,雖然在表中創建了符合UNIQUE 索引,可是全爲null的行仍是能夠插入的,而不是全爲null的重複行則不能夠插入。由於在UNIQUE約束中,(null,null)和(null,null)是不一樣的,固然在其餘一些狀況,好比說分組、集合操做中都認爲全是null是相等的 

7、null的排序 

order by默認升序(asc),這時候null是排在最後的,若是指定降序那麼null是排在最前面的,認爲null最大。

可是能夠用nulls first和nulls last進行調整。order by comm asc nulls first/last 

8、null與性能的關係 

Not null約束,定義約束是要付出消耗性能的代價的,由下面的測試能夠看出雖然約束檢查的很快,可是有時候仍是很消耗資源的,至少在這個例子上是這樣的,不須要not null約束,除非必要,不要亂定義約束。 

9、動態語句中的綁定變量與null 

在PL/SQL中動態SQL和動態PL/SQL常用綁定變量,這個綁定變量有個要求,就是不能直接傳入字面量null值,由於PL/SQL中動態語句要求傳入的綁定變量必須是SQL類型,而字面量null是無類型的,null字面量傳入是不能夠的。

固然能夠採用多種方法,若是必定要傳入null,則能夠將null改成空字符串、TO_NUMBER,TO_CHAR,TO_DATE等函數進行轉換,或定義一個未初始化的變量、直接傳入變量等。即不能定義一參數賦值null,必須先給予其餘的賦值結果。 

針對sqlserver的null的基本操做: 

1、使用 =null / <>null 默認狀況下的確不能使用 =null / <> null 來判斷 null 值如此。實際上 SQL Server 能夠 使用 SET ANSI_NULLS { ON | OFF } 設定來控制 =null / <>null 的行爲。

當 SET ANSI_NULLS 爲 ON 時,即便 column_name 中包含空值,使用 WHERE column_name = NULL的 SELECT 語句仍返回零行。

即便 column_name 中包含非空值,使用 WHERE column_name <> NULL 的 SELECT 語句仍會返回零行

可是當 SET ANSI_NULLS 爲 OFF 時,等於 (=) 和不等於 (<>) 比較運算符不遵照 ISO 標準。

使用 WHERE column_name = NULL 的 SELECT 語句返回 column_name 中包含空值的行。

使用 WHERE column_name <> NULL 的 SELECT 語句返回列中包含非空值的行。

此外,使用 WHERE column_name <> XYZ_value 的 SELECT 語句返回全部不爲 XYZ_value 也不爲 NULL的行。

 

2、 改變 null 值的鏈接行爲 SQL Server 提供 SET CONCAT_NULL_YIELDS_NULL { ON | OFF } 來控制null 與其它字符串鏈接的行爲。

當 SET CONCAT_NULL_YIELDS_NULL 爲 ON 時,串聯空值與字符串將產生 NULL 結果。例如, SELECT 'abc' + NULL 將生成 NULL 。

當 SET CONCAT_NULL_YIELDS_NULL 爲 OFF 時,串聯空值與字符串將產生字符串自己(空值做爲空字符串處理)。例如, SELECT 'abc' + NULL 將生成 abc 。

若是未指定 SET CONCAT_NULL_YIELDS ,則應用 CONCAT_NULL_YIELDS_NULL 數據庫選項的設置。

注:在 SQL Server 的將來版本中, CONCAT_NULL_YIELDS_NULL 將始終爲 ON ,並且將該選項顯式設置爲 OFF 的任何應用程序都將產生一個錯誤。 

3、變量的默認值與 null 值

命名一個變量後,若是沒有給它賦初始值,它的值就是 null 。有時候須要注意初始 null 值和經過 select 語句給變量後期賦 null 的區別。由於此 ‘null’ 非彼 ‘null’ 。

1. 子查詢中的 null

子查詢中出現的 null 值常常會被咱們忽視。

2. Case 語句中的 null

Case 中的 when 語句注意不要寫成 when null, 不然得不到想要的結果。 

4、 與 null 相關的函數

ISNULL ISNULL 檢測表達式是否爲 NULL ,若是是的話替換 NULL 值爲另一個值 COALESCE COALESCE函數返回指定表達式列表的第一個非 NULL 值 NULLIF 當指定的兩個表達式有相同值的時候 NULLIF 返回 NULL值,不然返回第一個表達式的值 

針對Sqlserver與Oracle中null值的不一樣: 

1、在SQL Server中與oracle正相反,NULL值會被認爲是一個無窮小的值,因此若是按照升序排列的話,則會被排在最前面

2、SQL Server和Oracle中對插入數據值包含空的處理有所差別,在SQL Server中,咱們能夠把表字段設計爲非空,但咱們仍然能夠經過下面語句執行插入操做:

INSERT INTO Table (TestCol) VALUES(‘’)

其中的TestCol字段,在設計的時候,已經被設計爲NOT NULL在sql server中,null和空格是不一樣的,也就是說,上面的語句插入的是一個空,但並非NULL,只有當咱們的插入語句中沒有該字段的時候,纔會被認爲違反非空的條件約束,若是把NULL翻譯成「空」的話,可能就會很容易搞混了。此外,若是咱們的字段是INT類型的話,若是咱們插入空的話,會獲得一個0,也就是說,Sql server會自動幫咱們處理對空格的轉化。

可是在Oracle中,這個便利便不存在了,必須嚴格按照規則來進行插入,也就是說,咱們再想視圖經過插入空來知足NOT NULL的設計約束,已經不能成功了,必須插入實實在在的內容才能符合NOT NULL的約束。

 注:這裏沒有將舉例copy過來,例子都是比較顯而易見的。瞭解了null的基本操做以後,就好尷尬啊。若是字段值中存儲了null值在oracle中咱們有想經過in的方式來查詢出來這個null值就基本不可能了。只有將字段進行函數處理nvl(column_name,’_NA_’) in(xxxx, ’_NA_’)來實現了,或者column_name in (xxxx) or column_name is null。

不過針對這些存儲了null的字段而且在查詢過程當中使用了in,多字段的查詢針對性的創建索引也是沒有什麼用的。null值也會給索引增長負擔,報表中的多條件查詢也不會同時都走上索引。只能乖乖的使用nvl來進行轉化後的篩選條件下的全掃描。

 

sql server 中order by 中關於null值處理

sqlserver 認爲 null 最小。 
升序排列:null 值默認排在最前。 
要想排後面,則:order by case when col is null then 1 else 0 end ,col 
降序排列:null 值默認排在最後。 
要想排在前面,則:order by case when col is null then 0 else 1 end , col desc

一、on 、where、having中把unknown看成FALSE處理,使用篩選器爲unknown的行會排除在外, 
而check約束中的unknown的值被當作true,假設一個check約束中要求salary大於0,插入salary爲null 
的行能夠被接受 NUll > 0 的結果爲unknown 
二、unique約束、排序、分組認爲兩個NULL是相等的 
若是表的一列被定義爲unique約束,將不能插入兩個爲NULL值得行 
group by 把全部null分爲一組 
order by 把全部的null值排列在一塊兒

select distinct top col from t order by col 先執行distinct –》order by –》top

相關文章
相關標籤/搜索