不再迷惑,無值和NULL值

来源:http://www.cnblogs.com/ljhdo/archive/2017/06/20/5128417.html
-Advertisement-
Play Games

在關係型資料庫的世界中,無值和NULL值的區別是什麼?一直被這個問題困擾著,甚至在寫TSQL腳本時,心有戚戚焉,害怕因為自己的一知半解,挖了坑,貽害後來人,於是,本著上下求索,不達通幽不罷休的決心(開個玩笑),遂有此文。 學習過關係型資料庫的伙伴都知道,NULL是指不確定的值,在資料庫中絕對是噩夢的 ...


在關係型資料庫的世界中,無值和NULL值的區別是什麼?一直被這個問題困擾著,甚至在寫TSQL腳本時,心有戚戚焉,害怕因為自己的一知半解,挖了坑,貽害後來人,於是,本著上下求索,不達通幽不罷休的決心(開個玩笑),遂有此文。

學習過關係型資料庫的伙伴都知道,NULL是指不確定的值,在資料庫中絕對是噩夢的存在;而空值,一般對字元串類型而言,指沒有任何值的字元串類型,為字元類型的變數設置為空值:set @vs='',空值跟無值不同。有人可能會問,無值是什麼?無值,是指數據表中沒有任何數據。無值和不確定值,單從字面意思上來看,兩者之間的定義很清楚,一旦深究,這兩者之間的關係,有時令人十分迷惑(confused),這是因為,在特定條件下,無值會轉換為NULL值。

一,舉個慄子,理解無值和NULL值的區別

比如,創建一個臨時表,在不插入任何數據時,該數據表是空的,沒有任何值,對其執行select命令,將不會返回任何數據值:

create table #temp
(
id int null
)

創建一個標量類型的變數,在不初始化時,該變數的值是不確定的,其值是NULL:

declare @vs int

創建一個表類型變數,在不初始化時,該表變數沒有任何數據,是無值的:

declare @vt as table
(
id int null
)

總結一下,聲明一個標量型變數,如果沒有對變數進行初始化,其值是不確定的,是NULL值;對於表變數,臨時表和基礎表,如果沒有插入任何數據,該表沒有任何數據,是無值的。

二,無值和NULL值的轉換

在開始本節之前,先為變數賦值,簡單的一個select命令就可以完成變數的賦值:

select @vs=1

有些朋友思維比較活躍,立馬會想到:“用select命令可以從表中取值為變數賦值”,對,但是,賦值方法不是我求索的重點,我關註的是從表中取值為變數賦值的結果。

1,從空表中為變數賦值

如果數據表是空表,沒有任何值,那麼資料庫引擎不會執行賦值語句,變數保持原有值不變:

select @vs=id
from #temp

但是,如果採用以下方式,那麼資料庫引擎會執行賦值語句,由於空表不返回任何值,資料庫引擎會把無值轉換為不確定值NULL:

select @vs=(select top 1 id
from #temp)

詫異嗎?無值和NULL值的轉換,居然從不起眼的變數賦值開始。註意,當不返回任何值時,資料庫引擎不確定返回值,就把無值轉換為NULL值。

2,從空表中計算聚合

空表是沒有任何數據的表,計算聚合會產生怎樣的結果?

select count(0) as count_all
    ,count(id) as count_id
    ,max(id) as max_id
    ,min(id) as min_id
    ,avg(id) as avg_id
    ,sum(id) as sum_id
from #temp

當統計數據行數時,返回的是0;當計算聚合函數(max,min,avg和sum)的聚合值時,由於無值可以聚合,資料庫引擎不能確定這些聚合函數的返回值,因此,資料庫引擎返回NULL值。

三,聚合函數忽略NULL值 

一般情況下,除了count(0),count(*)之外,聚合函數都會忽略NULL值,而統計非NULL值,如果讀者有疑問,可以查看我的博客《TSQL 聚合函數忽略NULL值》。如果只知聚合函數忽略NULL值,而不知空表也會產生結果為NULL的聚合值,輕易得出聚合函數不會返回NULL值的定論,那就很尷尬。樓主曾遇到過一次“意外”,在一次調試腳本代碼的過程中,我遇到max聚合函數返回NULL值的情況,當時一臉懵逼,直接懷疑自己之前的所學。

當聚合列值都是NULL值時,由於聚合函數忽略NULL值,因此,當計算聚合函數(max,min,avg和sum)的聚合值時,由於無值可以聚合,資料庫引擎不能確定這些聚合函數的返回值,因此,資料庫引擎返回NULL值。

insert into #temp(id)
values(null)

select count(0) as count_all
    ,count(id) as count_id
    ,max(id) as max_id
    ,min(id) as min_id
    ,avg(id) as avg_id
    ,sum(id) as sum_id
from #temp

聚合函數(max,min,sum,avg和count)忽略null值,但不代表聚合函數不返回null值:如果數據表為空表,或聚合列值都是null,那麼max,min,sum,avg聚合函數返回null值,而count 聚合函數返回0。聚合函數的共性:Null values are ignored。

 

 不再迷惑:當不返回任何值時,資料庫引擎不確定返回值,就把無值轉換為NULL值。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 還原SQL SERVER系統庫 共需還原三個系統庫,還原順序:master>msdb>model (1).資料庫配置管理器->資料庫服務屬性->啟動參數->添加“-m”後,重啟sql服務,資料庫就進入了單用戶模式。 (2).打開資料庫管理工具 (3).彈出連接服務視窗,點擊“取消” (4).點擊“新 ...
  • normal:表示普通索引 unique:表示唯一的,不允許重覆的索引,如果該欄位信息保證不會重覆例如身份證號用作索引時,可設置為unique full textl: 表示 全文搜索的索引。 FULLTEXT 用於搜索很長一篇文章的時候,效果最好。用在比較短的文本,如果就一兩行字的,普通的 INDE ...
  • 要啟動和關閉資料庫,必須要以具有Oracle 管理員許可權的用戶登陸,通常也就是以具有SYSDBA許可權的用戶登陸。一般我們常用SYS用戶以SYSDBA連接來啟動和關閉資料庫。下麵介紹Oracle資料庫幾種不同的資料庫啟動和關閉方式之間的區別以及它們各自不同的功能。 一、資料庫的啟動(STARTUP) ...
  • 1.通過mysql資料庫的user表查看用戶相關信息 2.創建資料庫 3.創建用戶 user表中host列的值的意義 % 匹配所有主機 localhost localhost不會被解析成IP地址,直接通過UNIXsocket連接 127.0.0.1 會通過TCP/IP協議連接,並且只能在本機訪問; ...
  • oracle trunc函數使用介紹 核心提示:oracle trunc函數使用介紹 1.TRUNC(for dates) TRUNC函數為指定元素而截去的日期值。 其具體的語法格式如下: TRUNC(date[,fmt]) 其中: date 一個日期值 fmt 日期格式,該日期將由指定的元素格式所 ...
  • 本文內容摘自《劍破冰山——Oracle開發藝術》一書。 1、避免對列運算 要善於通過等價改寫消除 SQL 中對列的運算,這樣可以避免索引無法使用。 2、消除隱式轉換 3、關註空格(避免粗心) 4、存儲過程與許可權 存儲過程有編譯和執行兩個階段,編譯階段,調用許可權和定義許可權是一樣的,而執行階段則不同。 ...
  • 本文內容摘自《劍破冰山——Oracle開發藝術》一書。 1、觸發器儘量考慮內部代碼過程封裝(解析次數) 2、避免動態 SQL 動態 SQL 和普通 SQL 在執行過程中最大的差別在於:動態 SQL 是在執行過程中編譯,而普通 SQL 是在過程執行前就已經編譯過了。如果過程中有大量動態 SQL,且執行 ...
  • # Redis 配置文件 # 當配置中需要配置記憶體大小時,可以使用 1k, 5GB, 4M 等類似的格式,其轉換方式如下(不區分大小寫)## 1k => 1000 bytes# 1kb => 1024 bytes# 1m => 1000000 bytes# 1mb => 1024*1024 byte ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...