3.6 SQL Server 查詢數據
SQL是一種特殊目的的編程語言,它是一種數據庫查詢和程序設計語言,用于存取數據以及查詢、更新和管理關系數據庫系統;同時也是數據庫腳本文件的擴展名。SQL語句無論是種類還是數量都是繁多的,很多語句也是經常要用到的,SQL查詢語句就是一個典型的例子,無論是高級查詢還是低級查詢,SQL查詢語句的需求是最頻繁的。
>[danger] ## 3.6.1 [SELECT]- 演示如何針對單個表查詢數據。
數據庫表是存儲數據庫中所有數據的對象。 在表中,數據按行和列格式邏輯組織,類似于電子表格(Excel)。
在表中,每行代表一個唯一記錄,每列代表記錄中的一個字段。 例如,`customers`表包含客戶數據,如客戶標識號,名字,姓氏,電話,電子郵件和地址信息,如下所示:

SQL Server使用模式對表和其他數據庫對象進行邏輯分組。 在示例數據庫(`bb_stores`)中,有兩個模式:`sales`和`production`。 `sales`模式將所有與銷售相關的表分組,而`production`模式將所有與生產相關的表分組。
要從表中查詢數據,請使用`SELECT`語句。 以下是`SELECT`語句的最基本形式:
~~~sql
SELECT
select_list
FROM
schema_name.table_name;
~~~
在上面語法中,
* 首先,`select_list`指定要在`SELECT`子句中查詢數據的逗號分隔列的列表。
* 其次,`schema_name.table_name`是在`FROM`子句中指定源表及其模式名稱。
處理SELECT語句時,SQL Server首先處理`FROM`子句,然后處理`SELECT`子句,即使SELECT子句首先出現在查詢中也是一樣。
## SQL Server SELECT語句示例
下面將使用示例數據庫中的`customers`表進行演示。

#### 1\. SQL Server SELECT檢索表部分列示例
以下查詢查找所有客戶的名字和姓氏:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers;
~~~
執行上面查詢語句,得到以下結果 -

查詢的結果稱為**結果集**。
以下語句返回所有客戶的名字,姓氏和電子郵件:
~~~sql
SELECT
first_name,
last_name,
email
FROM
sales.customers;
~~~
執行上面查詢語句,得到以下結果:

#### 2\. SQL Server SELECT從表中檢索所有列的示例
要從表的所有列獲取數據,可以指定選擇列表中的所有列。 還可以使用`SELECT *`作為速記來減少一些書寫:
~~~sql
SELECT
*
FROM
sales.customers;
~~~
執行上面查詢語句,得到以下結果:

`SELECT *`對于檢查不熟悉表的列和數據非常有用,它對即席查詢也很有幫助。
但是,由于以下主要原因,不應將`SELECT *`用于實際生產代碼:
* 首先,`SELECT *`經常檢索比應用程序需要運行的數據更多的數據。它會導致不必要的數據從SQL Server傳輸到客戶端應用程序,從而花費更多時間使數據通過網絡傳輸并減慢應用程序的速度。
* 其次,如果為表添加了一個或多個新列,則`SELECT *`只檢索包含新添加的列的所有列,這些列不打算在應用程序中使用,這可能會導致應用程序崩潰。
#### 3\. SQL Server SELECT - 對結果集進行排序
要根據一個或多個條件篩選行,請使用`WHERE`子句。在此示例中,查詢返回位于`CA`的客戶。如以下示例所示:
~~~sql
SELECT
*
FROM
sales.customers
WHERE
state = 'CA';
~~~
執行上面查詢語句,得到以下結果:

當WHERE子句可用時,SQL Server按以下順序處理查詢的子句:`FROM`,`WHERE`和`SELECT`。要基于一個或多個列對結果集進行排序,請使用`ORDER BY`子句,如以下示例所示:
~~~sql
SELECT
*
FROM
sales.customers
WHERE
state = 'CA'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,`ORDER BY`子句按名字按升序對客戶進行排序。在這種情況下,SQL Server按以下順序處理查詢的子句:`FROM`,`WHERE`,`SELECT`和`ORDER BY`。
#### 4\. SQL Server SELECT - 將行分組為組示例
要將行分組,請使用`GROUP BY`子句。 例如,以下語句將返回位于`CA`的所有客戶以及每個城市的客戶數量。參考以下查詢語句:
~~~sql
SELECT
city,
COUNT (*)
FROM
sales.customers
WHERE
state = 'CA'
GROUP BY
city
ORDER BY
city;
~~~
執行上面查詢語句,得到以下結果:

在這種情況下,SQL Server按以下順序處理子句:`FROM`,`WHERE`,`GROUP BY`,`SELECT`和`ORDER BY`。
#### 5\. SQL Server SELECT - 過濾分組示例
要根據一個或多個條件篩選組,請使用`HAVING`子句。以下示例返回`CA`州擁有10個以上客戶的城市:
~~~sql
SELECT
city,
COUNT (*)
FROM
sales.customers
WHERE
state = 'CA'
GROUP BY
city
HAVING
COUNT (*) > 10
ORDER BY
city;
~~~
執行上面查詢語句,得到以下結果:

請注意,`WHERE`子句在`HAVING`子句篩選器分組時篩選行。
>[danger] ## 3.6.2 [ORDER BY] - 根據指定列列表中的值對結果集進行排序
## SQL Server ORDER BY子句簡介
使用`SELECT`語句從表中查詢數據時,不保證結果集中的行順序。 這意味著SQL Server可以返回具有未指定行順序的結果集。
保證結果集中的行已排序的方法是使用`ORER BY`子句。 以下是`ORDER BY`子句的語法:
~~~sql
SELECT
select_list
FROM
table_name
ORDER BY
[column_name | expression] [ASC | DESC ]
~~~
在上面語法中,
* `column_name | expression` - 指定要對查詢結果集進行排序的列名或表達式。 如果指定多個列,則結果集按第一列排序,然后該排序結果集按第二列排序,依此類推。`ORDER BY`子句中出現的列必須對應于選擇列表中的列或`FROM`子句中指定的表中定義的列。
* `ASC | DESC` - 使用`ASC`或`DESC`指定是否應按升序或降序對指定列中的值進行排序。`ASC`將結果從最低值排序到最高值,而`DESC`將結果集從最高值排序到最低值。如果未明確指定`ASC`或`DESC`,則SQL Server將默認使用`ASC`來排序順序。 此外,SQL Server將`NULL`視為最低值。
處理具有`ORDER BY`子句的`SELECT`語句時,`ORDER BY`子句是要處理的最后一個子句。
## SQL Server ORDER BY子句示例
將使用[示例數據庫](http://www.yiibai.com/sqlserver/sql-server-sample-database.html "示例數據庫")中的`customers`表進行演示。

#### 1\. 按升序對結果集進行排序
以下語句按名字按升序對客戶列表進行排序:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers
ORDER BY
first_name;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,由于未指定`ASC`或`DESC`,`ORDER BY`子句默認使用`ASC`。
#### 2\. 按降序對結果集按一列排序
以下語句按名字降序對客戶列表進行排序。
~~~sql
SELECT
firstname,
lastname
FROM
sales.customers
ORDER BY
first_name DESC;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,因為顯式指定了`DESC`,所以`ORDER BY`子句按降序對`first_name`列中的值對結果集進行降序排序。
#### 3\. 按多列對結果集進行排序
以下語句檢索客戶的名字,姓氏和城市。 它首先按城市對客戶列表進行排序,然后按名字排序。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
city,
first_name;
~~~
執行上面查詢語句,得到以下結果:

#### 4\. 按多列和不同順序對結果集進行排序
以下語句按城市按降序對客戶進行排序,之后按第一個名稱按升序對排序結果進行排序。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
city DESC,
first_name ASC;
~~~
執行上面查詢語句,得到以下結果:

#### 5\. 按不在選擇列表中的列對結果集進行排序
可以通過選擇列表中未顯示的列對結果集進行排序。 例如,以下語句按`state`對客戶進行排序,即使`state`列未顯示在選擇列表中。
~~~sql
SELECT
city,
first_name,
last_name
FROM
sales.customers
ORDER BY
state;
~~~
執行上面查詢語句,得到以下結果:

請注意,`state`列在`customers`表中定義。 如果不是,那么查詢將無效。
#### 6\. 按表達式對結果集進行排序
`LEN()`函數返回字符串的字符數。 以下語句使用`ORDER BY`子句中的`LEN()`函數來檢索按名字長度排序客戶列表。
~~~sql
SELECT
first_name,
last_name,
LEN(first_name) as len_name
FROM
sales.customers
ORDER BY
LEN(first_name) DESC;
~~~
執行上面查詢語句,得到以下結果:

#### 7\. 按列的序數位置排序
SQL Server允許根據選擇列表中顯示的列的序號位置對結果集進行排序。
以下語句按名字和姓氏對客戶進行排序。 但是它沒有顯式指定列名,而是使用列的序號位置:
~~~sql
SELECT
first_name,
last_name
FROM
sales.customers
ORDER BY
1,
2;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,`1`表示`first_name`列,`2`表示`last_name`列。
由于幾個原因,在`ORDER BY`子句中使用列的序號位置是不推薦使用的。
* 首先,表中的列沒有序號位置,需要按名稱引用。
* 其次,當修改選擇列表時,可能忘記在`ORDER BY`子句中進行相應的更改。
因此,最好始終在`ORDER BY`子句中顯式指定列名。
>[danger] ## 3.6.3 [OFFSET FETCH] - 演示如何限制查詢返回的行數。
在本教程中,將學習如何使用SQL Server `OFFSET FETCH`子句來限制查詢返回的行數。
`OFFSET`和`FETCH`子句是`ORDER BY`子句的選項。 它們用于限制查詢返回的行數。
以下是`OFFSET`和`FETCH`子句的語法:
~~~sql
ORDER BY column_list [ASC |DESC]
OFFSET offset_row_count {ROW | ROWS}
FETCH {FIRST | NEXT} fetch_row_count {ROW | ROWS} ONLY
~~~
在上面語法中,
* `OFFSET`子句指定在開始從查詢返回行之前要跳過的行數。`offset_row_count`可以是大于或等于零的常量,變量或參數。
* `FETCH`子句指定在處理`OFFSET`子句后要返回的行數。 `offset_row_count`可以是大于或等于`1`的常量,變量或標量。
* `OFFSET`子句是必需的,而`FETCH`子句是可選的。 此外,`FIRST`和`NEXT`是同義詞,因此可以互換使用它們。
以下圖中說明了`OFFSET`和`FETCH`子句:

請注意,必須將`OFFSET`和`FETCH`子句與`ORDER BY`子句一起使用。 否則將收到錯誤消息。
`OFFSET`和`FETCH`子句比實現`TOP`子句更適合實現查詢分頁解決方案。
## SQL Server OFFSET和FETCH示例
下面將使用示例數據庫中的`products`表進行演示。

以下查詢返回`products`表中的所有產品,并按其價格和名稱對產品進行排序:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name;
~~~
執行上面示例查詢語句,得到以下結果 -

要跳過前`10`個產品并返回其余產品,請使用`OFFSET`子句,如以下語句所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name
OFFSET 10 ROWS;
~~~
執行上面示例查詢語句,得到以下結果 -

要跳過前`10`個產品并選擇接下來的`10`個產品,請使用`OFFSET`和`FETCH`子句,如下所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price,
product_name
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
~~~
執行上面示例查詢語句,得到以下結果 -

要獲得前`10`個最貴的產品,請使用`OFFSET`和`FETCH`子句,如下所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC,
product_name
OFFSET 0 ROWS
FETCH FIRST 10 ROWS ONLY;
~~~
執行上面示例查詢語句,得到以下結果 -

在此示例中,`ORDER BY`子句按價格按降序對產品進行排序。 然后,`OFFSET`子句跳過零行,`FETCH`子句從列表中獲取前`10`個產品。
>[danger] ## 3.6.4 [SELECT TOP] - 演示如何限制查詢結果集中返回的行數或行百分比。
在本教程中,將學習如何使用SQL Server `SELECT TOP`語句來限制查詢返回的行。
SELECT `TOP`子句用于限制查詢結果集中返回的行數或行百分比。
由于存儲在表中的行的順序是不可預測的,因此`SELECT TOP`語句始終與`ORDER BY`子句一起使用。 結果,結果集限于前`N`個有序行數。
以下是帶有`SELECT`語句的`TOP`子句的語法:
~~~sql
SELECT TOP (expression) [PERCENT]
[WITH TIES]
FROM
table_name
ORDER BY
column_name;
~~~
在此語法中,`SELECT`語句可以包含其他子句,如:`WHERE`,`JOIN`,`HAVING`和`GROUP BY`。
* `expression` - `TOP`關鍵字后面是一個表達式,它指定要返回的行數。 如果使用`PERCENT`,則將表達式計算為浮點值,否則將其轉換為`BIGINT`值。
* `PERCENT` - `PERCENT`關鍵字指示查詢返回前`N`個行百分比,其中`N`是表達式的結果。
* `WITH TIES` - `WITH TIES`用于返回更多行,其值與有限結果集中的最后一行匹配。 請注意,`WITH TIES`可能會導致返回的行數多于在表達式中指定的行數。
例如,如果要返回表達式最多的產品,可以使用`TOP 1`。但是,如果兩個或更多產品的價格與最貴的產品相同,那么會錯過結果集中其他最貴的產品。 為避免這種情況,可以使用`TOP 1 WITH TIES`。 它不僅包括第一個最貴的產品,還包括第二個,第三個,等等。
#### SQL Server SELECT TOP示例
下面將使用[示例數據庫]中的`production.products`表進行演示。
#### 1\. 使用具有恒定值的TOP
以下示例使用常量值返回前`10`個最貴的產品。
~~~sql
SELECT TOP 10
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### 2\. 使用TOP返回行的百分比
以下示例使用`PERCENT`指定結果集中返回的產品數。 `production.products`表有`321`行,因此,`321`的百分之一是分數值(`3.21`),SQL Server將其四舍五入到下一個整數,在這種情況下是`4`行記錄。
~~~sql
SELECT TOP 1 PERCENT
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### 3\. 使用TOP WITH TIES包含與最后一行中的值匹配的行
以下聲明返回了最貴的前三個產品:
~~~sql
SELECT TOP 3 WITH TIES
product_name,
list_price
FROM
production.products
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,第三個最貴的產品的定價為`6499.99`。 由于語句中使用`TOP WITH TIES`,因此它返回了另外價格與第三個相同的三個產品。
>[danger] # 過濾數據部分
>[danger] ## 1:) [DISTINCT] - 在表的一列或多列中選擇不同的值(消除相同的值)。
有時,可能希望僅在表的指定列中獲取不同的值。那么請使用`SELECT DISTINCT`子句,如下所示:
~~~sql
SELECT DISTINCT
column_name
FROM
table_name;
~~~
查詢僅返回指定列中的不同值。 換句話說,它從結果集中刪除列中的重復值。
如果使用多列,語法如下所示:
~~~sql
SELECT DISTINCT
column_name1,
column_name2 ,
...
FROM
table_name;
~~~
該查詢使用`SELECT`列表中所有指定列中的值組合來評估唯一性。
如果將`DISTINCT`子句應用于具有`NULL`值的列,則`DISTINCT`子句將僅保留一個`NULL`并消除其它的`NULL`值。 換句話說,`DISTINCT`子句將所有`NULL`值視為相同的值。
## SQL Server SELECT DISTINCT示例
為了方便演示,將使用示例數據庫中的`customers`表。表的結構如下所示:

#### A. DISTINCT一個字段的示例
以下語句返回`customers`表中所有客戶所在的所有城市:
~~~sql
SELECT
city
FROM
sales.customers
ORDER BY
city;
~~~
執行上面查詢語句,得到以下結果 -

從查詢輸出中可以清楚地看到,城市是重復的。
要獲取不同的城市唯一值,請按如下方式添加`DISTINCT`關鍵字:
~~~sql
SELECT DISTINCT
city
FROM
sales.customers
ORDER BY
city;
~~~
執行上面查詢語句,得到以下結果:

現在,查詢為每組重復項返回一個不同的值。也就是說它從結果集中刪除了所有重復的城市。
#### B. DISTINCT多列示例
以下語句查找所有客戶的不同城市和州。
~~~sql
SELECT DISTINCT
city,
state
FROM
sales.customers
~~~
執行以下查詢語句,得到以下結果 -

在此示例中,語句使用`city`和`state`列中的值組合來評估重復項。
#### C. DISTINCT帶有null值示例
以下示例查找客戶的不同(唯一)電話號碼:
~~~sql
SELECT DISTINCT
phone
FROM
sales.customers
ORDER BY
phone;
~~~
執行上面查詢語句,得到以下結果:

在此示例中,使用`DISTINCT`子句在`phone`列上,結果中刪除其他`NULL`僅保留一個`NULL`值。
>[danger] ## 2:) [WHERE] - 根據一個或多個條件過濾查詢輸出中的行
當使用`SELECT`語句查詢表中的數據時,將獲得表的所有行,這是顯然是不必要的,因為應用程序當時只能處理一組行。
要從表中獲取滿足一行或多個條件的行,請使用`WHERE`子句,如下所示:
~~~sql
SELECT
select_list
FROM
table_name
WHERE
search_condition;
~~~
在`WHERE`子句中,指定搜索條件以過濾`FROM`子句返回的行。 `WHERE`子句僅返回導致搜索條件計算為`TRUE`的行。
搜索條件是邏輯表達式或多個邏輯表達式的組合。 在SQL中,邏輯表達式通常稱為謂詞。
請注意,SQL Server使用三值謂詞邏輯,其中邏輯表達式可以計算為`TRUE`,`FALSE`或`UNKNOWN`。 `WHERE`子句不會返回導致謂詞計算結果為`FALSE`或`UNKNOWN`的任何行。
## SQL Server WHERE示例
我們將使用[示例數據庫]中的`products`表進行演示,表的結構如下:

#### A. 通過使用簡單的相等來查找行
以下語句檢索類別為`id`為`1`的所有產品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
category_id = 1
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### B. 查找滿足兩個條件的行
以下示例返回滿足兩個條件的產品:`category_id`為`1`,`model_year`為`2018`。它使用邏輯運算符`AND`來組合這兩個條件。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
category_id = 1 AND model_year = 2018
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### C. 使用比較運算符查找行
以下語句查找價格大于`300`且型號為`2018`的產品。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price > 300 AND model_year = 2018
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### D. 查找滿足兩個條件中的任何一個的行
以下查詢查找價格大于`3000`或型號為`2018`的產品。滿足其中一個條件的任何產品都包含在結果集中。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price > 3000 OR model_year = 2018
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

請注意,OR運算符用于組合謂詞。
#### E. 查找具有兩個值之間的值的行
以下語句查找價格介于`1899`和`1999.99`之間的產品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price BETWEEN 1899.00 AND 1999.99
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### F. 查找值列表中具有值的行
以下示例使用`IN`運算符查找價格為`299.99`或`466.99`或`489.99`的產品。
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
list_price IN (299.99, 369.99, 489.99)
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### G. 查找其值包含字符串的行
以下示例使用`LIKE`運算符查找名稱中包含字符串`Cruiser`的產品:
~~~sql
SELECT
product_id,
product_name,
category_id,
model_year,
list_price
FROM
production.products
WHERE
product_name LIKE '%Cruiser%'
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果:

>[danger] ## 3:) [AND] - 組合兩個布爾表達式,如果所有表達式都為真,則返回`true`。
在本教程中,將學習如何使用SQL Server `AND`運算符組合多個布爾表達式。
`AND`是一個邏輯運算符,用于組合兩個布爾表達式。僅當兩個表達式求值為`TRUE`時,它才返回`TRUE`。
以下說明了`AND`運算符的語法:
~~~sql
boolean_expression AND boolean_expression
~~~
`boolean_expression`是任何有效的布爾表達式,其計算結果為`TRUE`,`FALSE`和`UNKNOWN`。
## SQL Server AND運算符示例
我們將使用[示例數據庫]中的`products`表進行演示,表的結構如下:

#### A. 使用AND運算符示例
以下示例查找類別標識號(`category_id`)為`1`且價格大于`400`的產品:
~~~sql
SELECT
*
FROM
production.products
WHERE
category_id = 1
AND list_price > 400
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### B. 使用多個AND運算符示例
以下語句查找滿足以下所有條件的產品:類別編號(`category_id`)為`1`,價格大于`400`,品牌編號(`brand_id`)為`1`:
~~~sql
SELECT
*
FROM
production.products
WHERE
category_id = 1
AND list_price > 400
AND brand_id = 1
ORDER BY
list_price DESC;
~~~
執行上面查詢語句,得到以下結果:

#### C. 使用AND與其他邏輯運算符
請參閱以下查詢示例:
~~~sql
SELECT
*
FROM
production.products
WHERE
brand_id = 1
OR brand_id = 2
AND list_price > 1000
ORDER BY
brand_id DESC;
~~~
執行上面查詢語句,得到以下結果:

在這個例子中,在條件中使用了`OR`和`AND`運算符。與往常一樣,SQL Server首先評估`AND`運算符。因此,查詢檢索到品牌編號為`2`且價格大于`1000`的產品或品牌編號為`1`的產品。
要獲得品牌編號為`1`或`2`且價格大于`1000`的產品,請使用括號,如下所示:
~~~sql
SELECT
*
FROM
production.products
WHERE
(brand_id = 1 OR brand_id = 2)
AND list_price > 1000
ORDER BY
brand_id;
~~~
執行上面查詢語句,得到以下結果:

>[danger] ## 4:) [OR]- 組合兩個布爾表達式,如果其中一個條件為真,則返回`true`
SQL Server `OR`是一個邏輯運算符,用于組合兩個布爾表達式。當任一條件的計算結果為`TRUE`時,它返回`TRUE`。
以下顯示了`OR`運算符的語法:
~~~sql
boolean_expression OR boolean_expression
~~~
在此語法中,`boolean_expression`是任何有效的布爾表達式,其計算結果為:`true`,`false`和`unknown`。
在語句中使用多個邏輯運算符時,SQL Server將在`AND`運算符之后計算`OR`運算符。 但是,可以使用括號更改評估順序。
## SQL Server OR運算符示例
我們將使用[示例數據庫]中的`products`表進行演示,表的結構如下:

#### A. 使用OR運算符示例
以下示例查找價格小于`200`或大于`6000`的產品:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price < 200
OR list_price > 6000
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果 -

#### B. 使用多個OR運算符示例
以下語句查找品牌編號(`brand_id`)為`1`,`2`或`4`的產品:
~~~sql
SELECT
product_name,
brand_id
FROM
production.products
WHERE
brand_id = 1
OR brand_id = 2
OR brand_id = 4
ORDER BY
brand_id DESC;
~~~
執行上面查詢語句,得到以下結果 -

可以通過[IN運算符]替換多個`OR`運算符,如以下查詢所示:
~~~sql
SELECT
product_name,
brand_id
FROM
production.products
WHERE
brand_id IN (1, 2, 3)
ORDER BY
brand_id DESC;
~~~
#### C. 使用OR和AND運算符示例
請考慮以下示例:
~~~sql
SELECT
product_name,
brand_id,
list_price
FROM
production.products
WHERE
brand_id = 3
OR brand_id = 4
AND list_price > 100
ORDER BY
brand_id DESC;
~~~
執行上面查詢語句,得到以下結果 -

在這個例子中,使用了`OR`和`AND`運算符。 與往常一樣,SQL Server首先評估`AND`運算符。 因此,查詢返回品牌編號(`brand_id`)為`4`且價格大于`100`的產品或品牌編號(`brand_id`)為`3`的產品。
要查找品牌編號(`brand_id`)為`3`或`4`且價格大于`100`的產品,請使用括號,如以下查詢所示:
~~~sql
SELECT
product_name,
brand_id,
list_price
FROM
production.products
WHERE
(brand_id = 3 OR brand_id = 4)
AND list_price > 100
ORDER BY
brand_id;
~~~
執行上面查詢語句,得到以下結果 -

>[danger] ## 5:) [IN]- 檢查值是否與列表或子查詢中的任何值匹配。
`IN`運算符是一個邏輯運算符,用于測試指定的值是否與列表中的任何值匹配。
以下顯示了SQL Server `IN`運算符的語法:
~~~sql
column | expression IN ( v1, v2, v3, ...)
~~~
在上面語法中,
* 首先,`column | expression`指定要測試的列或表達式。
* 其次,指定要測試的值列表。所有值必須與列或表達式的類型具有相同的類型。
如果列或表達式中的值等于列表中的任何值,則`IN`運算符的結果為`TRUE`。
`IN`運算符等效于多個`OR`運算符,因此,以下謂詞是等效的:
~~~sql
column IN (v1, v2, v3)
column = v1 OR column = v2 OR column = v3
~~~
要取消`IN`運算符,請使用`NOT IN`運算符,如下所示:
~~~sql
column | expression NOT IN ( v1, v2, v3, ...)
~~~
如果列或表達式不等于列表中的任何值,則`NOT IN`運算符的結果為`TRUE`。
除了值列表之外,還可以使用子查詢返回帶有`IN`運算符的值列表,如下所示:
~~~sql
column | expression IN (subquery)
~~~
在此語法中,子查詢是一個`SELECT`語句,它返回單個列的值列表。請注意,如果列表包含`NULL`,則`IN`或`NOT IN`的結果將為`UNKNOWN`。
## SQL Server OR運算符示例
我們將使用[示例數據庫]中的`products`表進行演示,表的結構如下:

#### A. SQL Server IN帶有值列表示例
以下語句查找價格為以下值之一的產品:`89.99`,`109.99`和`159.99`:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price IN (89.99, 109.99, 159.99)
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果 -

上面的查詢等效于以下使用`OR`運算符的查詢:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price = 89.99 OR list_price = 109.99 OR list_price = 159.99
ORDER BY
list_price;
~~~
要查找價格不是上述價格的產品,請使用`NOT IN`運算符,如以下查詢中所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
list_price NOT IN (89.99, 109.99, 159.99)
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果 -

#### B. SQL Server IN帶有子查詢的示例
以下查詢返回位于商店編號(`store_id`)為`1`中,其數量大于或等于`30`的產品的產品編號列表:
~~~sql
SELECT
product_id
FROM
production.stocks
WHERE
store_id = 1 AND quantity >= 30;
~~~
執行上面查詢語句,得到以下結果 -

可以將上面的查詢用作子查詢,如以下查詢所示:
~~~sql
SELECT
product_name,
list_price
FROM
production.products
WHERE
product_id IN (
SELECT
product_id
FROM
production.stocks
WHERE
store_id = 1 AND quantity >= 30
)
ORDER BY
product_name;
~~~
執行上面查詢語句,得到以下結果 -

在這個例子中:
* 首先,子查詢返回了產品ID列表。
* 其次,外部查詢檢索產品名稱和產品ID與子查詢返回的任何值匹配的產品價格。
>[danger] ## 6:) [BETWEEN]- 測試值是否在指定范圍值之間。
## SQL Server BETWEEN運算符簡介
`BETWEEN`運算符是一個邏輯運算符,用于指定要測試值的范圍。
以下是`BETWEEN`運算符的語法:
~~~sql
column | expression BETWEEN start_expression AND end_expression
~~~
在上面語法中,
* `column | expression` - 指定要測試的列或表達式。
* 將`start_expression`和`end_expression`放在`BETWEEN`和`AND`關鍵字之間。 `start_expression`,`end_expression`和要測試的表達式必須具有相同的數據類型。
如果要測試的表達式大于或等于`start_expression`的值且小于或等于`end_expression`的值,則`BETWEEN`運算符返回`TRUE`。
可以使用大于或等于(`>=`)且小于或等于(`<=`)來替換`BETWEEN`運算符,如下所示:
~~~sql
column | expression <= end_expression AND column | expression >= start_expression
~~~
使用`BETWEEN`運算符的條件比使用比較運算符`>=`,`<=`和邏輯運算符AND的條件更具可讀性。
要取消`BETWEEN`運算符的結果,請使用`NOT BETWEEN`運算符,如下所示:
~~~sql
column | expression NOT BETWEEN start_expression AND end_expresion
~~~
如果列或表達式中的值小于`start_expression`的值且大于`end_expression`的值,則`NOT BETWEEN`將返回`TRUE`。 它相當于以下條件:
~~~sql
column | expression < start_expression AND column | expression > end_expression
~~~
請注意,如果`BETWEEN`或`NOT BETWEEN`的任何輸入為`NULL`,則結果為`UNKNOWN`。
## SQL Server BETWEEN示例
讓我們舉一些使用`BETWEEN`運算符的例子,以了解它是如何工作的。
#### A. SQL Server BETWEEN兩個數字示例
我們將使用[示例數據庫]中的`products`表進行演示,表的結構如下:

以下查詢查找價格介于`149.99`和`199.99`之間的產品:
~~~sql
SELECT
product_id,
product_name,
list_price
FROM
production.products
WHERE
list_price BETWEEN 149.99 AND 199.99
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果:

要獲得價格不在`149.99`和`199.99`范圍內的產品,請使用`NOT BETWEEN`運算符,如下所示:
~~~sql
SELECT
product_id,
product_name,
list_price
FROM
production.products
WHERE
list_price NOT BETWEEN 149.99 AND 199.99
ORDER BY
list_price;
~~~
執行上面查詢語句,得到以下結果:

#### B. SQL Server BETWEEN兩個日期示例
請考慮以下`orders`表,結構如下所示:

以下查詢查找客戶在2017年1月15日至2017年1月17日期間下的訂單:
~~~sql
SELECT
order_id,
customer_id,
order_date,
order_status
FROM
sales.orders
WHERE
order_date BETWEEN '20170115' AND '20170117'
ORDER BY
order_date;
~~~
執行上面查詢語句,得到以下結果:

請注意,要指定日期常量,請使用格式:`'YYYYMMDD'`,其中`YYYY`是`4`位數年份,例如:`2019`,`MM`是`2`位數月份,例如:`01`,`DD`是`2`位數日,例如`15`。
>[danger] ## 7:) [LIKE]- 檢查字符串是否與指定的模式匹配。
## SQL Server LIKE運算符簡介
SQL Server `LIKE`是一個邏輯運算符,用于確定字符串是否與指定的模式匹配。 模式可以包括常規字符和通配符。`LIKE`運算符用于:`SELECT`,`UPDATE`和`DELETE`語句的`WHERE`子句中,以根據模式匹配過濾行。
以下說明了SQL Server `LIKE`運算符的語法:
~~~sql
column | expression LIKE pattern [ESCAPE escape_character]
~~~
**pattern**
模式是要在列或表達式中搜索的字符序列。它可以包含以下有效通配符:
* 通配符百分比(`%`):任何零個或多個字符的字符串。
* 下劃線(`_`)通配符:任何單個字符。
* `[list of characters]`通配符:指定集合中的任何單個字符。
* `[character-character]`:指定范圍內的任何單個字符。
* `[^]`:不在列表或范圍內的任何單個字符。
通配符使`LIKE`運算符比等于(`=`)和不等于(`!=`)字符串比較運算符更靈活。
**轉義符**
* 轉義字符指示`LIKE`運算符將通配符視為常規字符。轉義字符沒有默認值,必須僅計算為一個字符。
如果列或表達式與指定的模式匹配,則`LIKE`運算符返回`TRUE`。要取消`LIKE`運算符的結果,可以使用`NOT`運算符,如下所示:
~~~sql
column | expression NOT LIKE pattern [ESCAPE escape_character]
~~~
## SQL Server LIKE示例
請參閱示例數據庫中的以下`customers`表:

#### A. %(百分比)通配符示例
以下示例查找姓氏(`last_name`)以字母`z`開頭的客戶:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE 'z%'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

以下示例返回姓氏(`last_name`)以字符串`er`結尾的客戶信息:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '%er'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

以下語句檢索姓氏(`last_name`)以字母`t`開頭并以字母`s`結尾的客戶:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE 't%s'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

#### B. \_(下劃線)通配符示例
下劃線代表單個字符。 例如,以下語句返回第二個字符為字母`u`的客戶:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '_u%'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

在上面查詢中,`_u%`模式解釋說明如下 -
* 第一個下劃線字符(`_`)匹配任何單個字符。
* 第二個字母`u`完全匹配字母`u`。
* 第三個字符`%`匹配任何字符序列。
#### C. \[list of characters\]通配符示例
帶有字符列表的方括號,例如:`[ABC]`表示單個字符,必須是列表中指定的字符之一。
例如,以下查詢返回姓氏(`last_name`)中第一個字符為`Y`或`Z`的客戶:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[YZ]%'
ORDER BY
last_name;
~~~
執行上面查詢語句,得到下結果 -

#### D. \[character-character\]通配符示例
具有字符范圍的方括號,例如`[A-C]`表示必須在指定范圍內的單個字符。
例如,以下查詢查找客戶,其中姓氏中的第一個字符是范圍`A`到`C`中的字母:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[A-C]%'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

#### E. \[^字符列表或范圍\]通配符示例
帶有插入符號(`^`)后跟范圍,例如`[A-C]`或字符列表,例如`[^ABC]`的方括號表示不在指定范圍或字符列表中的單個字符。
例如,以下查詢返回姓氏中的第一個字符不是范圍`A`到`X`中的字母的客戶信息:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
last_name LIKE '[^A-X]%'
ORDER BY
last_name;
~~~
執行上面查詢語句,得到下結果 -

#### F. NOT LIKE運算符示例
以下示例使用`NOT LIKE`運算符查找名字中第一個字符不是字母`A`的客戶:
~~~sql
SELECT
customer_id,
first_name,
last_name
FROM
sales.customers
WHERE
first_name NOT LIKE 'A%'
ORDER BY
first_name;
~~~
執行上面查詢語句,得到下結果 -

>[danger] ## 8:) [列和表別名]- 顯示如何使用列別名來更改查詢輸出和表別名的標題,以提高查詢的可讀性
1.使用as 字句來改變結果集中列的名稱
2.使用"空格" 來改變結果集中列的別名
- 第三章-數據庫
- 3.1 SQL Server簡介及安裝
- 3.2 SQL Server示例數據庫
- 3.3 SQL Server 加載示例
- 3.3 SQL Server 中的數據類型
- 3.4 SQL Server 數據定義語言DDL
- 3.5 SQL Server 修改數據
- 3.6 SQL Server 查詢數據
- 3.7 SQL Server 連表
- 3.8 SQL Server 數據分組
- 3.9 SQL Server 子查詢
- 3.10.1 SQL Server 集合操作符
- 3.10.2 SQL Server聚合函數
- 3.10.3 SQL Server 日期函數
- 3.10.4 SQL Server 字符串函數