SELECT * FROM task_tasks ORDER BY taskid LIMIT 5,1
limit X,Y 中X表示跳過X個數據,讀取Y個數據
SELECT * FROM task_tasks ORDER BY taskid LIMIT 5 OFFSET 3
offset X是跳過X個數據,limit Y是選取Y個數據
6.使用注釋:注釋使用-- (兩個連字符)嵌在行內。-- 之后的文本就是注釋
SELECT prod_name -- 這是一條注釋
FROM Products;
第 3 課 排序檢索數據
1.子句(clause) SQL 語句由子句構成,有些子句是必需的,有些則是可選的。一個子 句通常由一個關鍵字加上所提供的數據組成。子句的例子有我們在前 一課看到的 SELECT 語句的 FROM 子句。
2.ORDER BY 子句取一個或多個列的名字,據此對輸出進行排序。 3.排序數據
SELECT prod_name
FROM Products
ORDER BY prod_name;
ORDER BY 子句的位置 在指定一條 ORDER BY 子句時,應該保證它是 SELECT 語句中最后一條子句。 如果它不是最后的子句,將會出現錯誤消息。
4.按多個列排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;
檢索 3 個列,并按其中兩個列對結果進行排序——首先按價
格,然后按名稱排序
多個列排序應用在:姓名排序—首先按姓排序,然后在每個姓中再按名排序
5.按列位置排序—不懂
按列位置排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3;
SELECT 清單中指定的是選擇列的相對位置而不是列名。ORDER BY 2
表示按 SELECT 清單中的第二個列 prod_name 進行排序。ORDER BY 2,
3 表示先按 prod_price,再按 prod_name 進行排序
組合 WHERE 子句 SQL 允許給出多個 WHERE 子句。這些子句有兩種使用方式, 即以 AND 子句或 OR 子句的方式使用
操作符(operator):用來聯結或改變 WHERE 子句中的子句的關鍵字,也稱為邏輯操作符(logical operator)
AND操作符:要通過不止一個列進行過濾,可以使用 AND 操作符給 WHERE 子句附加條件(and后的條件要連著where都滿足才能篩選出結果)
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4;
AND:用在 WHERE 子句中的關鍵字,用來指示檢索滿足所有給定條件的行(子句只包含一個 AND 子句,因此最多有兩個過濾條件)
SELECT * FROM task_tasks WHERE `status`=1 AND userid=1
ORDER BY builddate
OR操作符:OR 操作符與 AND 操作符正好相反,它指示 DBMS 檢索匹配任一條件的行【事實上,許多 DBMS 在 OR WHERE 子句的第一個條件得到滿足的情況下,就不再計算第二個條件了(在第一個條件滿足時,不管第二個條件是否滿足,相應的行都將被檢索出來)?!?/li>
SELECT prod_name, prod_price
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = ‘BRS01’;
求值順序
SELECT prod_name, prod_price
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'
AND prod_price >= 10;
需要列出價格為10美元及以上,且由DLL01或BRS01
制造的所有產品
SELECT * FROM task_tasks WHERE taskname='旅游' OR taskname='哈哈哈1'
AND builddate ='2007-03-06'
在 WHERE 子句中使用圓括號 任何時候使用具有 AND 和 OR 操作符的 WHERE 子句,都應該使用圓括號明確地分組操作符。 不要過分依賴默認求值順序,即使它確實如你希望的那樣。 使用圓括號沒有什么壞處,它能消除歧義
IN 操作符:IN 操作符用來指定條件范圍,范圍中的每個條件都可以進行匹配。IN 取一組由逗號分隔、括在圓括號中的合法值
SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ( 'DLL01', 'BRS01' )
ORDER BY prod_name;
此 SELECT 語句檢索由供應商 DLL01 和 BRS01 制造的所有產品。
IN 操作符后跟由逗號分隔的合法值,這些值必須括在圓括號中。你可能會猜測 IN 操作符完成了與 OR 相同的功能,恭喜你猜對了!下面
的 SQL 語句完成與上面的例子相同的工作
SELECT prod_name, prod_price
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'
ORDER BY prod_name;
IN操作符:WHERE 子句中用來指定要匹配值的清單的關鍵字,功能與 OR 相當。
NOT 操作符 WHERE 子句中的 NOT 操作符有且只有一個功能,那就是否定其后所跟的任何條件。因為 NOT 從不單獨使用(它總是與其他操作符一起使用),所以它的語法與其他操作符有所不同。NOT 關鍵字可以用在要過濾的列前,而不僅是在其后
NOT操作符:WHERE 子句中用來否定其后條件的關鍵字
SELECT prod_name
FROM Products
WHERE NOT vend_id = 'DLL01'
ORDER BY prod_name;
列出除 DLL01 之外的所有供應商制造的產品上面的例子也可以使用<>操作符來完成
SELECT prod_name
FROM Products
WHERE vend_id <> 'DLL01'
ORDER BY prod_name;
SELECT * FROM task_tasks WHERE NOT `status`=1 ORDER BY builddate
NOT優勢:在與 IN 操作符聯合使用時,NOT 可以非常簡單地找出與條件列表不匹配的行。
第 6 課 用通配符進行過濾
通配符:百分號(%)、下劃線(_)、方括號([ ])、(+)或(||)、
LIKE 操作符 通配符(wildcard) 用來匹配值的一部分的特殊字符 搜索模式(search pattern) 由字面值、通配符或兩者組合構成的搜索條件。
通配符本身實際上是 SQL 的 WHERE 子句中有特殊含義的字符,SQL 支持 幾種通配符。 為在搜索子句中使用通配符,必須使用 LIKE 操作符。LIKE指示 DBMS,后跟的搜索模式利用通配符匹配而不是簡單的相等匹配進行比較 注意:通配符搜索只能用于文本字段(字符串),非文本數據類型字段不能使用通配符搜索。
百分號(%)通配符:最常使用的通配符是百分號(%)。在搜索串中,%表示任何字符出現任意次數
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'Fish%';
找出所有以詞 Fish 起頭的產品
SELECT * FROM task_tasks WHERE taskname LIKE '%放假%'
Access 通配符:如果使用的是 Microsoft Access,需要使用*而不是%
區分大小寫 根據 DBMS 的不同及其配置,搜索可以是區分大小寫的。如果區分大小寫,則’fish%'與 Fish bean bag toy 就不匹配
通配符可在搜索模式中的任意位置使用,并且可以使用多個通配符
搜索模式'%bean bag%'表示匹配任何位置上包含文本 bean bag 的值, 不論它之前或之后出現什么字符 注意:需要特別注意,除了能匹配一個或多個字符外,%還能匹配 0 個字符。%代表搜索模式中給定位置的 0 個、1 個或多個字符 請注意 NULL 通配符%看起來像是可以匹配任何東西,但有個例外,這就是 NULL。 子句 WHERE prod_name LIKE '%'不會匹配產品名稱為 NULL 的行
下劃線(_)通配符:下劃線的用途與%一樣,但它只匹配單個字符,而不是多個字符
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '__ inch teddy bear';
SELECT * FROM task_tasks WHERE taskname LIKE '放_'
一個下劃線占一位
SELECT * FROM task_tasks WHERE taskname LIKE '放假__'
與%能匹配 0 個字符不同,_總是剛好匹配一個字符,不能多也不能少
方括號([ ])通配符:用來指定一個字符集,它必須匹配指定位置(通配符的位置)的一個字符
并不總是支持集合 與前面描述的通配符不一樣,并不是所有 DBMS 都支持用來創建集合的[]。只有微軟的 Access 和 SQL Server 支持集合。為確定你使用的DBMS 是否支持集合,請參閱相應的文檔。
FROM Customers
WHERE cust_contact LIKE '[JM]%'
ORDER BY cust_contact;
SELECT COUNT(*) AS num_prods
FROM Products
WHERE vend_id = 'DLL01';
創建分組——groupby
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id
SELECT `status` FROM task_tasks
GROUP BY `status`
GROUP BY 子句必須出現在 WHERE 子句之后,ORDER BY 子句之前。
過濾分組:HAVING 子句 目前為止所學過的所有類型的 WHERE 子句都可以用 HAVING 來替代。 唯一的差別是,WHERE過濾行,而 HAVING 過濾分組(HAVING 支持所有 WHERE 操作符 )
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
過濾 COUNT(*) >= 2(兩個以上訂單)的那些分組
HAVING 和 WHERE 的差別 這里有另一種理解方法,WHERE 在數據分組前進行過濾,HAVING 在數據分組后進行過濾。這是一個重要的區別,WHERE 排除的行不包括在分組中。這可能會改變計算值,從而影響 HAVING 子句中基于這些值過濾掉的分組
SELECT vend_id, COUNT(*) AS num_prods
FROM Products
WHERE prod_price >= 4
GROUP BY vend_id
HAVING COUNT(*) >= 2;
列出具有兩個以上產品且其價格大于等于 4 的供應商
使用 HAVING 和 WHERE HAVING 與 WHERE 非常類似,如果不指定 GROUP BY,則大多數 DBMS會同等對待它們。不過,你自己要能區分這一點。 使用 HAVING 時應該結合 GROUP BY 子句,而 WHERE 子句用于標準的行級過濾
分組和排序 order by和group by差異
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3;
檢索包含三個或更多物品的訂單號和訂購物品的數目
SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING COUNT(*) >= 3
ORDER BY items, order_num;
要按訂購物品的數目排序輸出,需要添加 ORDER BY 子句,
語法
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_numFROM OrderItemsWHERE prod_id = 'RGAN01');
在 SELECT 語句中,子查詢總是從內向外處理
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01'));
為了執行上述 SELECT 語句,DBMS 實際上必須執行三條 SELECT 語句。
最里邊的子查詢返回訂單號列表,此列表用于其外面的子查詢的 WHERE
子句。外面的子查詢返回顧客 ID 列表,此顧客 ID 列表用于最外層查詢
的 WHERE 子句。最外層查詢返回所需的數據
作為計算字段使用子查詢
SELECT COUNT(*) AS orders
FROM Orders
WHERE cust_id = '1000000001';
碼對顧客 1000000001 的訂單進行計數
-------------------------
要對每個顧客執行 COUNT(*),應該將它作為一個子查詢
SELECT cust_name,cust_state,(SELECT COUNT(*)FROM OrdersWHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers
ORDER BY cust_name; 這條 SELECT 語句對 Customers 表中每個顧客返回三列:
cust_name、cust_state 和 orders。orders 是一個計算字段,
它是由圓括號中的子查詢建立的。
該子查詢對檢索出的每個顧客執行一次。
在此例中,該子查詢執行了 5 次,因為檢索出了 5 個顧客。子查詢中的 WHERE 子句與前面使用的 WHERE 子句稍有不同,
因為它使用了完全限定列名,而不只是列名( cust_id)。
它指定表名和列名Orders.cust_id 和 Customers.cust_id)。
下面的 WHERE 子句告訴 SQL,
比較Orders表中的cust_id和當前正從Customers表中檢索的cust_id:
WHERE Orders.cust_id = Customers.cust_id用一個句點分隔表名和列名,
在有可能混淆列名時必須使用這種語法。
在這個例子中,有兩個 cust_id 列:一個在 Customers 中,另一個在Orders 中。
如果不采用完全限定列名,DBMS 會認為要對 Orders 表中的 cust_id 自身進行比較。
因為SELECT COUNT(*) FROM Orders WHERE cust_id = cust_id
總是返回 Orders 表中訂單的總數,而這個結果不是我們想要的:
SELECT cust_name, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
FROM OrderItems
WHERE prod_id = 'RGAN01'));
以上等效為
SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num
AND prod_id = 'RGAN01';
第 13 課 創建高級聯結
如何使用表別名,如何對被聯結的表使用聚集函數
使用表別名:主要原因是能在一條 SELECT 語句中不止一次引用相同的表
給字段起別名
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')'
AS vend_title
FROM Vendors
ORDER BY vend_name; 給表起別名
SELECT cust_name, cust_contact
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num
AND prod_id = 'RGAN01';
預期效果:給與 Jim Jones 同一公司的所有顧客發送一封信件。這個查詢要求
首先找出 Jim Jones 工作的公司,然后找出在該公司工作的顧客
寫法一:
SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name = (SELECT cust_name
FROM Customers
WHERE cust_contact = 'Jim Jones');
方法二:連表(此表是相同一張)
SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';
SELECT C.*, O.order_num, O.order_date,
OI.prod_id, OI.quantity, OI.item_price
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
AND OI.order_num = O.order_num
AND prod_id = 'RGAN01';
在這個例子中,通配符只對第一個表使用。所有其他列明確列出,
所以沒有重復的列被檢索出來
事實上,我們迄今為止建立的每個內聯結都是自然聯結,很可能永遠都 不會用到不是自然聯結的內聯結
外聯結:許多聯結將一個表中的行與另一個表中的行相關聯,但有時候需要包含 沒有關聯行的那些行。
外聯——左聯
檢索包括沒有訂單顧客在內的所有顧客
SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
ON Customers.cust_id = Orders.cust_id; 外聯——右聯
SELECT Customers.cust_id, Orders.order_num
FROM Customers RIGHT OUTER JOIN Orders
ON Orders.cust_id = Customers.cust_id;
SELECT Customers.cust_id, Orders.order_num
FROM Orders FULL OUTER JOIN Customers
ON Orders.cust_id = Customers.cust_id;
使用帶聚集函數的聯結
檢索所有顧客及每個顧客所下的訂單數,使用 COUNT()函數完成
SELECT Customers.cust_id,COUNT(Orders.order_num) AS num_ord
FROM Customers INNER JOIN OrdersON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;
聚集函數也可以方便地與其他聯結一起使用
外聯-左聯
SELECT Customers.cust_id,COUNT(Orders.order_num) AS num_ord
FROM Customers LEFT OUTER JOIN OrdersON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;
創建組合查詢 可用 UNION 操作符來組合數條 SQL 查詢。利用 UNION,可給出多條 SELECT 語句,將它們的結果組合成一個結果集
使用UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';等效于
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')OR cust_name = 'Fun4All
UNION規則 ? UNION 必須由兩條或兩條以上的 SELECT 語句組成,語句之間用關鍵 字UNION分隔(因此,如果組合四條SELECT語句,將要使用三個UNION 關鍵字)。 ? UNION 中的每個查詢必須包含相同的列、表達式或聚集函數(不過, 各個列不需要以相同的次序列出)。 ? 列數據類型必須兼容:類型不必完全相同,但必須是 DBMS 可以隱含 轉換的類型(例如,不同的數值類型或不同的日期類型)。
包含或取消重復的行:UNION 從查詢結果集中自動去除了重復的行;換句話說,它的行為與一條 SELECT 語句中使用多個 WHERE 子句條件一樣。 這是 UNION 的默認行為,如果愿意也可以改變它。事實上,如果想返回 所有的匹配行,可使用 UNION ALL 而不是 UNION。
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';
UNION 與 WHERE 這一課一開始我們說過,UNION 幾乎總是完成與多個 WHERE 條件相同 的工作。UNION ALL 為 UNION 的一種形式,它完成 WHERE 子句完成 不了的工作。如果確實需要每個條件的匹配行全部出現(包括重復行), 就必須使用 UNION ALL,而不是 WHERE
對組合查詢結果排序 SELECT 語句的輸出用 ORDER BY 子句排序。在用 UNION 組合查詢時,只能使用一條 ORDER BY 子句,它必須位于最后一條 SELECT 語句之后。 對于結果集,不存在用一種方式排序一部分, 而又用另一種方式排序另一部分的情況,因此不允許使用多條 ORDER BY 子句
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All'
ORDER BY cust_name, cust_contact;
INSERT INTO Customers
VALUES('1000000006','Toy Land','123 Any Street','New York','NY','11111','USA',NULL,NULL); 存儲到表中每一列的數據在 VALUES 子句中給出,必須給每一列提供一個值如果某列沒有值,如上面的 cust_contact 和 cust_email 列,則應該使用 NULL 值(假定表允許對該列指定空值)
INTO 關鍵字 在某些 SQL 實現中,跟在 INSERT 之后的 INTO 關鍵字是可選的。但 是,即使不一定需要,最好還是提供這個關鍵字,這樣做將保證 SQL 代碼在 DBMS 之間可移植。
INSERT INTO Customers(cust_id,cust_contact,cust_email,cust_name,cust_address,cust_city,cust_state,cust_zip)
VALUES('1000000006',NULL,NULL,'Toy Land','123 Any Street','New York','NY','11111'); INSERT 語句填充所有列(與前面的一樣),但以一種不同的次序填充因為給出了列名,所以插入結果仍然正確
插入部分行:使用這種語法,還可以省略列,這表示可以只給某些列提供值,給其他列不提供值。
INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)
VALUES('1000000006','Toy Land','123 Any Street','New York','NY','11111','USA');
沒有給 cust_contact 和 cust_email 這兩列提供值。
這表示沒必要在 INSERT 語句中包含它們。因此,這里的 INSERT
語句省略了這兩列及其對應的值
輸入▼
CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_idAND OrderItems.order_num = Orders.order_num;
分析▼
這條語句創建一個名為 ProductCustomers 的視圖,它聯結三個表,返
回已訂購了任意產品的所有顧客的列表。如果執行 SELECT * FROM
ProductCustomers,將列出訂購了任意產品的顧客
檢索訂購了產品 RGAN01 的顧客
輸入▼
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';輸出▼
cust_name cust_contact
------------------- ------------------
Fun4All Denise L. Stephens
The Toy Store Kim Howard
詳細看書介紹P160-165
EXECUTE AddNewProduct( 'JTS01','Stuffed Eiffel Tower',6.49,'Plush stuffed toy with the text La
?Tour Eiffel in red white and blue' ); 這里執行一個名為 AddNewProduct 的存儲過程,將一個新產品添加到Products 表中。
AddNewProduct 有四個參數,分別是:
供應商 ID(Vendors 表的主鍵)、產品名、價格和描述。
這 4 個參數匹配存儲過程中 4 個預期變量(定義為存儲過程自身的組成部分)。
此存儲過程將新行添加到 Products 表,并將傳入的屬性賦給相應的列詳細看書P170-174