数据检索 | 2.2 检索单个列 | SELECT prod_name FROM Products; | SQL语句不区分大小写 |
2.3 检索多个列 | SELECT prod_name,prod_id,prod_price FROM Products; | ||
2.4 检索所有列 | SELECT * FROM Products; | ||
2.5 检索不同的值 | SELECT DISTINCT vend_id FROM Products; | ||
2.6 限制结果 | SELECT TOP 5 prod_name FROM Products;(SQL server、Access) SELECT prod_name FROM Products FETCH FIRST 5 ROWS ONLY;(DB2) SELECT prod_name FROM Products WHERE ROWNUM <=5;(Oracle) SELECT prod_name FROM Products LIMIT 5;(MySQL、SQLite等) SELECT prod_name FROM Products LIMIT 4 OFFSET 3;(LIMIT 3,4) |
从第3行起的4行数据 | |
2.7 使用注释 | SELECT prod_name --这是一条注释(--之后的是注释) FROM Products; # 这是一条注释 (单行注释) /*这是一条注释,很长 (跨行注释,通常用于代码注释) 很长的注释*/ |
||
排序检索数据 | 3.1 排序数据 | SELECT prod_name FROM Products ORDER BY prod_name; | 字母升序拍;可以通过非检索列进行排序 |
3.2 按多个列排序 | SELECT prod_name,prod_id,prod_price FROM Products ORDER BY prod_price,prod_name; |
prod_price相同时才按照prod_name | |
3.3 按列位置排序 | SELECT prod_name,prod_id,prod_price FROM Products ORDER BY 2,3; |
表示先按prod_id,再按prod_price排序 | |
3.4 指定排序方向 | SELECT prod_name,prod_id,prod_price FROM Products ORDER BY prod_price DESC; |
降序排列,大小写字母在排序时是否区分取决于数据库的配置 | |
SELECT prod_name,prod_id,prod_price FROM Products ORDER BY prod_price DESC,prod_name; |
prod_name仍为升序,ASC表升序(默认) | ||
过滤数据 | 4.1 使用WHERR | SELECT prod_name,prod_price FROM Products WHERE prod_price = 3.49; |
|
SELECT prod_name,prod_price FROM Products WHERE prod_price = 3.49 ORDER BY prod_name; |
WHERE和ORDER BY组合用法 | ||
4.2 WHERE子句操作符 | =,<>,!=,<,<=,!<,>,>=,!>,BETWEEN,IS NULL | ||
4.2.2 不匹配检查 | SELECT vend_id,prod_name FROM Products WHERE vend_id<>'DLL01'; |
不匹配检查,字符串需要加引号<>与!=等价 | |
4.2.3 范围值检查 | SELECT prod_name,prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10 |
包括5和10 | |
4.2.4 空值检查 | SELECT prod_name,prod_price FROM Products WHERE prod_price IS NULL; |
NULL与非匹配:空值不会被返回 | |
高级数据过滤 | 5.1.1 AND操作符 | SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price<=4; |
可用多个AND,增加过滤条件 |
5.1.2 OR操作符 | SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'; |
第一个条件满足时,不管第二个条件是否满足,相应行都被检索出来 | |
SELECT prod_id,prod_price,prod_name FROM Products WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01')AND prod_price<=10; |
组合使用,使用圆括号。AND优先级较高 | ||
5.2 IN操作符 | SELECT prod_name,prod_price FROM Products WHERE vend_id = IN( 'DLL01','BRS01') ORDER BY prod_name; |
功能与OR相当 | |
SELECT prod_name,prod_price FROM Products WHERE vend_id = 'DLL01'OR vend_id = 'BRS01' ORDER BY prod_name; |
改写IN语句 | ||
5.3 NOT操作符 | SELECT prod_name FROM Products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name; |
||
SELECT prod_name FROM Products WHERE vend_id <> 'DLL01' ORDER BY prod_name; |
改写NOT语句 | ||
用通配符进行过滤 | 6.1.1 %通配符 | SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE 'Fish%'; |
找出以Fish起头的词,Fish之后可以是0个字符;Acess需要使用*非%;大小写是否区分取决于数据库配置 |
SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE '%bean bag%'; |
匹配任何包含bean bag的值 | ||
SELECT prod_name FROM Products WHERE prod_name LIKE 'F%y'; |
匹配F开头,y结尾的值(b%@forta.com) %匹配0个、1个、多个字符 如果字符末尾是空格,则需要用F%y%来匹配 |
||
WHERE prod_name LIKE '%'; | 不配匹配prod_name为NULL的行 | ||
6.1.2 _通配符 | SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE '__ inch teddy bear'; |
DB2不支持,Access用?非_ _只匹配单个字符,功能与%通,如需匹配2个字符,则需要使用__ |
|
6.1.2 []通配符 | SELECT cust_contact FROM Customers WHERE cust_contract LIKE '[JM]%' ORDER BY cust_contract; |
找出所有J或M起头的名字 只有Access和SQL server支持 |
|
SELECT cust_contact FROM Customers WHERE cust_contract LIKE '[^JM]%' ORDER BY cust_contract; |
找出所有非J或M起头的名字 Access需要用!非^ |
||
创建计算字段 | 7.2 拼接字段 | SELECT vend_name + '('+ vend_country +')' FROM Vendors ORDER BY vend_name; |
Access、SQL server使用+ DB2、Oracle、SQLite使用|| |
SELECT Concat(vend_name,'('vend_country,')')' FROM Vendors ORDER BY vend_name; |
MySQL使用函数Concat 返回结果两个字段之间有空格 |
||
SELECT RTRIM(vend_name) + '('+ RTRIM(vend_country) + ')' FROM Vendors ORDER BY vend_name; |
RTRIM()去掉字符串右边的空格 LTRIM()去掉字符串左边的空格 TRIM()去掉字符串左右两边的空格 |
||
SELECT RTRIM(vend_name) + '('+ RTRIM(vend_country) + ')' AS vend_title FROM Vendors ORDER BY vend_name; |
使用别名:单词或字符串 | ||
7.3 执行算术计算 | SELECT prod_id,quantity,item_price, quantity*item_price AS expanded_price FROM OrderItems WHERE order_num = 20008; |
expanded_price是一个计算字段 算术操作符:+、-、*、/ |
|
测试计算 | SELECT 3*2 SELECT Trim('abc') SELECT Now() |
返回6 返回abc 返回当前日期和时间 |
|
使用函数处理数据 | 8.1 函数 | MID():Access SUBSTR():DB2、Oracle、SQLite SUBSTRING():MySQL、SQL server |
提取字符串组成部分 |
使用多种函数:Access、Oracle CAST():DB2 CONVERT():MySQL、SQL server |
数据类型转换 | ||
NOW():Access CURRENT_DATE:DB2 CURDATE():MySQL SYSDATE:Oracle GETDATE():SQL server DATE():SQLite |
取当前日期 | ||
8.2.1 文本处理函数 | SELECT vend_name UPPER(vend_name) AS vend_name_upcase FROM Vendors ORDER BY vend_name; |
将文本转化为大写 | |
常用文本处理函数 | LEFT() LENGTH() 也可使用DATALENGTH()或LEN() LOWER() Access使用LCASE() LTRIM() RIGHT() RTTIM() SOUNDEX() UPPER() |
返回字符串左边的字符 返回字符串的长度 将字符串转换为小写 去掉字符串左边的空格 返回字符串右边的字符 去掉字符串右边的空格 返回字符串的SOUNDEX值(按照发音过滤) 将字符串转换为大写 |
|
8.2.2 日期和时间处理函数 | SELECT order_num FROM Orders WHERE DATEPART(yy,order_date)=2012; |
SQL server DATEPART()返回日期的某一部分(年份) |
|
SELECT order_num FROM Orders WHERE DATEPART('yyyy',order_date)=2012; |
Access | ||
SELECT order_num FROM Orders WHERE to_number(to_char(order_date,'YYYY'))=2012; |
Oracle没有DATEPART()函数 | ||
SELECT order_num FROM Orders WHERE order_date BETWEENto_date('01-01-2012') AND to_date('12-31-2012') |
BETWEEN改写 | ||
SELECT order_num FROM Orders WHERE strftime('%Y',order_date)= '2012'; |
SQLite小技巧 | ||
SELECT order_num FROM Orders WHERE YEAR(order_date)= 2012; |
MySQL、MariaDB | ||
8.2.3 数值处理函数 | ABS()、COS()、PI()、SIN()、SQRT()、TAN() EXP()返回一个的指数值 |
||
汇总数据 | 9.1 聚集函数 | AVG() COUNT() MAX() MIN() SUM() |
返回某列的平均数 返回某列的行数 返回某列的最大值 返回某列的最小值 返回某列数值之和 |
9.1.1 AVG()函数 | SELECT AVG(prod_price) AS avg_price FROM Products; | avg_price是别名,AVG()忽略值值为NULL的行 | |
SELECT AVG(prod_price) AS avg_price FROM Products WHERE vend_id = 'DLL01'; |
组合过滤 | ||
9.1.2 COUNT()函数 | SELECT COUNT(*) AS num_cust FROM Customers; | 对表中行的数目进行统计,包括空、非空、NULL | |
SELECT COUNT(cust_email) AS num_cust FROM Customers; | 只对具有email的客户计数 指定列名时会忽略值为空的行若使用COUNT(*)不忽略 |
||
9.1.3 MAX()函数 | SELECT MAX(prod_price) AS max_price FROM Products; | MAX()一般用来找出最大数值或日期值。忽略NULL行 MAX()用于文本数据时,返回该列排序后的最后一行 |
|
9.1.4 MAX()函数 | SELECT MIN(prod_price) AS min_price FROM Products; | MIN()一般用来找出最小数值或日期值。忽略NULL行 MIN()用于文本数据时,返回该列排序后最前面的行 |
|
9.1.5 SUM()函数 | SELECT SUM(quantity) AS items_ordered FROM OrderItems WHERE order_num = 20005; |
返回订单中所有物品数量之和 | |
SELECT SUM(item_price*quantity) AS total_price FROM OrderItems WHERE order_num = 20005; |
SUM()忽略NULL行 SUM()也可以用来合计计算值 |
||
9.2 聚集不同值 | SELECT AVG(DISTINCT prod_price) AS avg_price FROM Products WHERE vend_id = 'DLL01'; |
||
9.3 组合聚集函数 | SELECT COUNT(*) AS num_items, MIN(prod_price),AS price_min MAX(prod_price),AS price_max AVG(prod_price),AS price_avg FROM Products; |
||
分组数据 | 10.1 数据分组 | SELECT COUNT(*) AS num_prods FROM Products WHERE vend_id = 'DLL01' |
|
10.2 创建分组 | SELECT vend_id,COUNT(*) AS num_prods FROM Products GROUP BY vend_id; |
GROUP子句出现在WHERE后 ORDER BY子句之前 | |
GROUP BY 2,1; | 通过相对位置指定列,先按列2分组,再按列1分组 | ||
10.3 过滤分组 | SELECT vend_id,COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*)>=2; |
HAVING与GROUP BY结合使用 | |
SELECT cust_id,COUNT(*) AS num_prods FROM Products WHERE prod_price >=4 GROUP BY vend_id HAVING COUNT(*)>=2; |
WHERE和HAVING组合 | ||
10.4 分组和排序 | SELECT order_num,COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*)>=3 ORDER BY items,order_num; |
Access不支持别名排序 | |
10.5 SELECT子句顺序 | SELECT 要返回的列或表达式 FROM 从中检索数据的表 WHERE 行级过滤 GROUP BY 分组说明 HAVING 组级过滤 ORDER BY 输出排序顺序 |
||
使用子查询 | 11.2 利用子查询进行过滤 | SELECT cust_id FROM Orders WHERE order_num IN (SELECT order_num FROM OrderItmes WHERE prod_id = 'RGAN01') |
|
11.2.1 | SELECT cust_name,cust_contact FROM Customers WHERE cust_id IN(SELECT cust_id FROM Orders WHERE order_num IN (SELECT order_num FROM OrderItmes WHERE prod_id = 'RGAN01')); |
||
11.3 作为计算字段使用子查询 | SELECT cust_name,cust_state,(SELECT COUNT(*) FROM Orders WHERE Order.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name; |
完全限定列名:表明.列名 | |
联结表 | 12.2 创建联结 | SELECT vend_name,prod_name,prod_price FROM Vendors,Products WHERE Vendors.vend_id = Product.vend_id; |
列名来自两个不同的表 通过WHERE子句构造关系 |
12.2.2 内联结 | SELECT vend_name,prod_name,prod_price FROM Vendors INNER JOIN Products ONVendors.vend_id = Product.vend_id; |
效果同上 | |
12.2.3 联结多个表 | SELECT prod_name,vend_name,prod_price,quantity FROM OrderItems,Products,Vendors WHERE Product.vend_id = Vendors.vend_id AND OrderItems.prod_id = Product.vend_id AND order_num = 20007; |
联结的表越多,性能下降的越厉害 | |
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_num 'RGAN01'; |
改写11.2.1 | ||
创建高级联结(待补充) | 13.1 | ||
组合查询 | 14.2.1 使用UNION | UNION用在两条SELECT语句之间,把输出整合成一个结果集 | |
14.2.4 对组合查询结果排序 | 在最后加ORDER BY,不允许有多种排序方式 | ||
插入数据 | 15.1 数据插入 | 插入完整的行、行的一部分、某些查询结果 | |
15.1.1 插入完整的行 | INSERT INTO Customer VALUES ('1000000006','Yoy Land','123 Any Street','New York','NY','11111','USA',NULL,NULL); |
有些SQL中INTO可以省略 某列没有值,则应使用NULL值(允许空值时) |
|
INSERT INTO Customer(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email) VALUES('1000000006','Yoy Land','123 Any Street','New York','NY','11111','USA',NULL,NULL); |
更为安全,列名顺序可以自由调整,与数据匹配即可 | ||
15.1.2 插入部分行 | INSERT INTO Customer(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country) VALUES('1000000006','Yoy Land','123 Any Street','New York','NY','11111','USA'); |
有两列是空值(NULL),未进行插入 | |
15.1.3 插入检索出的数据 | INSERT INTO Customer(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country) SELECT cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country FROM CustNew; |
检索出多少行就插入多少行(0、1、2...) INSERT通常只插入一行 |
|
15.2 从一个表复制到另一个表 | SELECT * INTO CustCopy FROM Customers; SELECT cust_id,cust_name INTO CustCopy FROM Customers; CREATE TABLE CustCopy AS SELECT * FROM Customers; |
创建一个名为CustCopy的新表复制表Customers的全部内容 可以只复制指定的列 MySQL、Oracle、SQLite的语法 |
|
更新和删除数据 | 16.1 更新数据 | UPDATE Customers SET cust_email = 'hotpsy@126.com' WHERE cust_id = '001'; |
|
UPDATE Customers SET cust_cntact = 'hotpsy', SET cust_email = 'hotpsy@qq.com' WHERE cust_id = '002'; |
更新多个列 | ||
UPDATE Customers SET cust_email = NULL WHERE cust_id = '003'; |
设置为NULL可以表示删除列的值,如果该列允许设置为NULL | ||
16.2 删除数据 | DELETE FROM Customers WHERE cust_id = '004'; |
||
TRUNCATE Customers | 删除整个表 | ||
创建和操作表 | 17.1 创建表(也可以使用工具) | CREAT TABLE Products( prod_id CHAR(10) NOT NULL, vend_id CHAR(10) NOT NULL, prod_name CHAR(254) NOT NULL, prod_price DECIMAL(8,2) NOT NULL, prod_desc VARCHAR(10) NULL); |
|
17.1.3 指定默认值 | CREAT TABLE Products( prod_id CHAR(10) NOT NULL, vend_id CHAR(10) NOT NULL, prod_name CHAR(254) NOT NULL, prod_price DECIMAL(8,2) NOT NULL DEFAULT 2, prod_desc VARCHAR(10) NULL); |
||
获得系统日期 | Access: NOW() DB2: CURRENT_DATE MySQL: CURRENT_DATE() Oracle: SYSDATE PostgreSQL:CURRENT_DATE SQL Server:GETDATE() SQLite:date('now') |
||
17.2 更新表 | ALTER TABLE Vendors ADD vend_phone CHAR(20); |
增加一列vend_phone | |
ALTER TABLE Vendors DROP COLUMN vend_phone CHAR(20); |
删除列vend_phone | ||
17.3 删除表 | DROP TABLE CustCopy | 删除表没有确认 | |
17.4 重命名表 | Oracle、MySQL: ALTER TABLE 表名 rename to 新表名 SQL server:sp_rename SQLite:ALTER TABLE |
无标准,各个DB实现不同 | |
使用视图 | |||
使用存储过程 | 19.3 执行存储过程 | EXECUTE AddNewProduct('JTS01','Stuffed Eiffel Tower',6.49,'xxxx') | |
19.3 创建存储过程 | CREATE PROCEDURE MailingListCount(ListCount OUT INTEGER) IS v_rows INTEGER; BEGIN SELECT COUNT(*) INTO v_rows FROM Customers WHERE NOT CUST_email IS NULL; ListCount := v_rows; END; |
Oracle版本 | |
var ReturnValue NUMBER EXEC MailingListCount(:ReturnValue); SELECT ReturnValue; |
调用Oracle例子 | ||
管理事务处理 | 20.1 事务处理 | 事务、回退、提交、保留点 | |
20.2 控制事务处理 | SET TRANSACTION … |
Oracle | |
BEGIN TRANSACTION … COMMIT TRANSACTION |
SQL server | ||
20.2.1 使用ROLLBACK | DELETE FROM Orders; ROLLBACK; |
回退(撤销)SQL语句 | |
20.2.2 使用COMMIT | SET TRANSACTION DELETE OrderItems WHERE order_num = 12345; DELETE Orders WHERE order_num = 12345; COMMIT; |
||
20.2.3 使用保留点 | ... SAVEPOINT delete1; ... ROLLBACK TRANSACTION |
||
使用游标 | |||
高级SQL特性 |
http://files.cnblogs.com/files/hotpsy/SQL%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A%E6%91%98%E8%A6%81.rar