数据库事物四大特性。
1原子性,操作要么全做,要么全不做。
2隔离性,就是任何一个事物在执行的时候不会受到其他事物的干扰。
3一致性,比如一个人转账,必定一方减少钱。一方增加钱。保持一致。
4持久性,对于事物的某一个操作,它对数据库的改变是永久的。不可更改的。
A表,a_id,a_name,a_tel三个字段。
B表,b_id,b_address,b_sol三个字段。关联表,ref_id,a_id,b_id,存储着AB两表的id,
比如:A有
a0001,zhang3,139555533
a0002,li4,1397788888
a0003,wang5,13655566
B有
b0001,shanghai,234
b0002,shenyang,332
b0003,chongqing,123
如果想要AB表多对多的话,只需要将关联表进行增加即可,而AB两表基本数据不变,
比如:
关联表ref_table:
r0001,a0001,b0002
r0002,a0001,b0001
r0003,a0001,b0003
r0004,a0002,b0003
通过联合查询,就可以得到多对多的数据了,而且不破坏基本数据表。
检索不同的值
SELECT DISTINCT vend_id
FROM Products; 没有重复的 警告:不能部分使用DISTINCT
DISTINCT关键字作用于所有的列,不仅仅是跟在其后的那一列。例如,你指定SELECT DISTINCT vend_id, prod_price,除非指定的两列完全相同,否则所有的行都会被检索出
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3; ORDER BY 相对列位置升序 按照 prod_price先排, 再按prod_name排序.
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC; 降序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC, prod_name; 降序 prod_name仍然升序 如果想在多个列上进行降序排序,必须对每一列指定DESC关键字。
SELECT prod_name, prod_price
FROM Products
WHERE prod_price = 3.49; 警告:WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后,否则将会产生错误
SELECT vend_id, prod_name
FROM Products
WHERE vend_id <> 'DLL01'; <> 相当于不等于!=
SELECT prod_name, prod_price
FROM Products
WHERE prod_price BETWEEN 5 AND 10; 5-10之间的值
SELECT prod_name
FROM Products
WHERE prod_price IS NULL; 空字段,不是价格为0
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4; 同时满足
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; AND的优先级高 所以要加括号
SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ( 'DLL01', 'BRS01' )
ORDER BY prod_name; 每个条件都可以匹配 必须加括号.
in的优点
为什么要使用IN操作符?其优点为:
在有很多合法选项时,IN操作符的语法更清楚,更直观。
在与其他AND和OR操作符组合使用IN时,求值顺序更容易管理。
IN操作符一般比一组OR操作符执行得更快(在上面这个合法选项很少的例子中,你看不出性能差异)。
IN的最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE子句。第11课会对此进行详细介绍。
SELECT prod_name
FROM Products
WHERE NOT vend_id = 'DLL01'
ORDER BY prod_name; WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'Fish%'; 从技术上说,LIKE是谓词而不是操作符 Fish开头的所有匹配的。百分号(%)通配符 区分大小写
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '%bean bag%'; 可以使用多个%
SELECT prod_name
FROM Products
WHERE prod_name LIKE 'F%y'; F开头y结尾。
警告:请注意NULL
通配符%看起来像是可以匹配任何东西,但有个例外,这就是NULL。子句WHERE prod_name LIKE '%'不会匹配产品名称为NULL的行
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '__ inch teddy bear'; 下划线_只匹配单个字符
SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE '[JM]%'
ORDER BY cust_contact; 所有J或者M开头的联系人。 否定形式[^JM]
SELECT cust_contact
FROM Customers
WHERE NOT cust_contact LIKE '[JM]%'
ORDER BY cust_contact; 和上面那个例子一样的效果
输入
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')' //添加括号
FROM Vendors
ORDER BY vend_name;
输出
Bear Emporium (USA)
Bears R Us (USA)
Doll House Inc. (USA)
Fun and Games (England)
Furball Inc. (USA)
Jouets et ours (France)
RTRIM()函数去掉值右边的所有空格。通过使用RTRIM(),各个列都进行了整理。
在使用GROUP BY子句前,需要知道一些重要的规定。
GROUP BY子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致地进行数据分组。
如果在GROUP BY子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
GROUP BY子句中列出的每一列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。
大多数SQL实现不允许GROUP BY列带有长度可变的数据类型(如文本或备注型字段)。
除聚集计算语句外,SELECT语句中的每一列都必须在GROUP BY子句中给出。
如果分组列中包含具有NULL值的行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
这条SELECT语句的前三行类似于上面的语句。最后一行增加了HAVING子句,它过滤COUNT(*) >= 2(两个以上订单)的那些分组。
可以看到,WHERE子句在这里不起作用,因为过滤是基于分组聚集值,而不是特定行的值。
说明:HAVING和WHERE的差别
这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,
WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id; 内联结 没有联结会返回笛卡儿积
BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 12345
DELETE Orders WHERE order_num = 12345
COMMIT TRANSACTION
分析▼
在这个SQL Server例子中,从系统中完全删除订单12345。因为涉及更新两个数据库表Orders和OrderItems,所以使用事务处理块来保证订单不被部分删除。
最后的COMMIT语句仅在不出错时写出更改。如果第一条DELETE起作用,但第二条失败,则DELETE不会提交。