SQL小结
1. 一般而言,除非你确实需要表中的每一列,否则最好别使用*通配符。虽然使用通配符让你自己省事,不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。
2. DISTINCT关键字作用于所有的列,不仅仅是跟在其后面的那一列。
3. Limit:第一个被检索的行是第0行,而不是第一行。因此,LIMIT 1 offset 1 会检索第2行,而不是第1行。
4. MySQL支持简化版的LIMIT 4 OFFSET 3语句,即LIMIT 3,4 。使用这个语法,逗号之前的值对应OFFSET,逗号之后的值对应LIMIT。
5. 注释:-- 这是一条注释;/**/ 多行注释。
6. 检索出来的数据并不是随机显示的。如果不排序,数据一般将以它在底层表中的顺序显示,这有可能是数据最初添加到表中的顺序。但是,
如果数据随后进行过更新或删除,那么这个顺序将会受到DBMS重用回收存储空间的方式的影响。
7. ORDER BY 放到 SELECT语句的最后。
8. ORDER BY 后面的列默认按升序排序,如果需要指定列的排序规则,需要每个列单独指定。例如:如果想在多个列上进行降序,必须对每一列
指定DESC关键字。ORDER BY prode_pice DESC,prod_name DESC;
9. ASC没有多大用处,因为升序是默认的(如果既不指定ASC也不指定DESC,则假定为ASC)。
10. 在字典排序顺序中,A被视为与a相同,这是大多数数据库管理系统的默认行为。
11. BETWEEN匹配范围内所有的值,包括指定的开始值和结束值。
12. 通过过滤选择不包含指定值的所有行时,你可能希望范围含null值得行。但是这做不到,因为未知有特殊的含义,数据库不知道它们是否匹配,所以在进行匹配过滤或非匹配过滤时,不会返回这些结果。
即:不等于,不会返回符合条件的null值。
13. 许多DBMS在OR WHERE子句的第一个条件得到满足的情况下,就不再计算第二个条件了。
14. SQL在处理OR操作符前,优先处理AND操作符。
任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确第分组操作符。不要过分依赖默认求值顺序,即使它确实如你希望的那样。使用圆括号没有什么坏处,他能消除歧义。
15. 为什么要使用IN操作符?其优点如下:
1). 在很多合规选项时,IN操作符的语法更清楚,更直观。
2). 在与其他AND和OR操作组合使用IN时,求值顺序更容易管理。
3). IN操作符一般比一组OR操作符执行的更快
4). IN的最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE子句。
16. 通配符搜索只能用于文本字段(字符串),非文本数据类型字段不能使用通配符搜索。
17. 根据DBMS不同及其配置,搜索可以是区分大小写的。
18. 除了能匹配一个或多个字符串,%还能匹配0个字符。%代表搜索模式中给定位置的0个,1个或多个字符。
19. %不会匹配值为NULL的行。
20. 下划线"_" 模糊匹配单个字符。注意,两位数字需要两个下划线匹配。
21. SQL的通配符很有用。但这种功能是有代价的,即通配符搜索一般比前面讨论的其他搜索要耗费更长的处理时间。
22. TRIM(字段)去除字段中的空格。RTRIM(字段)去除右边的空格,LTRIM(字段)去除左边的空格。
23. Concat(字段,字段2) 拼接字段
24. 在很多DBMS种,AS关键字是可选的,不过最好使用它,这被视为一条最佳实践。
25. SELECT语句为测试、检验函数和计算提供了很好的方法。虽然SELECT通常用于从表中检索数据,但是省略了FROM子句后就是简单地访问和处理表达式,例如SELECT 3*2 ;将返回6,SELECT Trim(' abc '); 将返回abc,
SELECT Now();使用Now()函数返回当前日期和时间。
26. 日期和时间值以特殊的格式存储,以便能快速和有效地排序或过滤,并且节省物理存储。
27. MySQL可以使用名为YEAR(时间字段)的函数从日期中提取年份。mysql 日期处理函数有哪些?
28. AVG(),MAX(),MIN(),SUM(),COUNT(字段) 会忽略NULL值。COUNT(*) 不会忽略NULL值。
29.虽然MAX()一般用来找出最大的数据值或日期,但许多(并非所有)DBMS允许将它用来返回任意列中的最大值,包括返回文本中的最大值。在用于文本数据时,MAX()返回按该列排序后的最后一行。
30. 虽然MIN()一般用来找出最小的数据值或日期,但许多(并非所有)DBMS允许将它用来返回任意列中的最小值,包括返回文本中的最小值。在用于文本数据时,MIN()返回按该列排序后的最前面一行。
31. SELECT后面可以跟 字段运算例如:SELECT item_price*quantity 和 SELECT sum(item_price*quantity)
32. 在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名。
33. 使用GROUP BY 分组时,如果列中包含NULL值得行,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
34. GROUP BY 子句必须出现在WHERE子句之后,ORDER BY 子句之前。
35. WHERE 在数据分组前进行过滤,HAVING在数据分组后进行过滤。
36. HAVING 与 WHERE 非常类似,如果不指定GROUP BY,则大多数DBMS会同等对待它们。不够,你自己要能区分一点。使用HAVING时应该结合
GROUP BY子句,而WHERE子句用于标准的行级过滤。
37. 作为子查询的SELECT语句只能查询单个列。企图检索多个列将返回错误。
38. SELECT cust_name,cust_state,(select count(*) from orders where orders.cust_id = customers.cust_id) as orders from customers order by cust_name
该子查询对检索出的每个顾客执行一次。在此例中,该子查询执行了5次,因为检索出了5个顾客。
39. 由没有联结条件的额表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
40. 基于两个表之间的相等测试,称为 等值联结,也称为 内联结(inner join)。
41. DBMS在运行时关联指定的每个表,以处理联结。这种处理可能非常耗费资源,因此应该注意,不要联结不必要的表。联结的表越多,性能下降的越厉害。
42. 自联结通常作为外部语句,用来替代从相同表中检索数据的使用子查询语句。虽然最终的结果时相同的,但许多DBMS处理联结远比处理子查询快的多。应该试一下两种方案,以确定哪一种的性能更好。
43. 与内联结关联两个表中的行不同的是,外联结还包括没有关联行的行。在使用OUTER JOIN 语法时,必须使用RIGHT或LEFT关键字指定包含其所有行的表(RIGHT支出的是OUTER JOIN右边的表,而LEFT 指出的是OUTER JOIN左边的表)。
44. 还存在另一种外联结,就是全外联结(full outer join),它检索两个表中的所有行并关联那些可以关联的行。与左外联结和右外联结包含一个表的不关联行不同,全外联结包含两个表的不关联的行。语句:FULL OUTER JOIN
45. UNION 从查询结果集中自动去除了重复的行;换句话说,它的行为与一条SELECT语句中使用多个WHERE子句条件一样。这是UNION的默认行为,如果想返回所有匹配行,可以使用UNION ALL而不是UNION。
46. 在用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT 语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种排序另外一部分的情况。
47. UNION在最后一条SLECT语句后使用了ORDER BY子句。虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上DBMS将用它排序所有SELEDT语句返回所有结果。
48. INSERT SELECT。顾名思义,它是由一条INSERT语句和一条SELECT语句组成的。INSERT INOT CUSTOMERS(字段1,字段2,字段3) SELECT 字段1,字段2,字段3 from custNew . (ps: 列名不要求一样)
49. 从一个表复制到另一个表:SELECT * INTO CustCopy FROM Customers 。 要想复制一部分列,可以明确给出列名,而不是使用*通配符。
50. CREATE TABLE CustCopy AS SELECT * FROM Customers;
51. 在使用SELECT INOT时,需要知道一些事情:
1). 任何SELECT选项和子句都可以使用,包括:WHERE 和 GROUP BY
2). 可以利用联结从多个表插入数据
3). 不管多少个表中检索数据,数据都只能插入到一个表中。
42. SELECT INTO是实验新SQL语句前进行表复制的很好工具。先进行复制,可在复制的数据上测试SQL代码,而不会影响实际的数据。
43 使用UPDATE时一定要细心。因为稍不注意,就会更新表中的所有数据。
44. DELETE 后面的 FROM 有些DBMS可选,建议带上,移植性更好。
45. 如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,而速度更快(因为不记录数据的变动)。
46. 在UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT 进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。
47. 有的DBMS允许数据库管理员施加约束,防止执行不带WHERE子句的UPDATE或DELETE语句。如果所采用的DBMS支持这个特性,应该使用它。
48. 主键是其值唯一标识表中每一行的列。只有不允许NULL值得列可以作为主键,允许NULL值得列不能作为唯一标识。
49. MYSQL可以指定当前时间为默认时间:DEFALUT CURRENT_DATE()
50. 最好设置默认值???
51. 复杂的表结构更改一般需要手动删除过程,它涉及一下步骤:
1). 用新的列布局创建一个新表
2). 使用INSERT SELECT语句从旧表复制数据到新表。
3). 检验包含所需数据的新表;
4). 重命名旧表(如果确定,可以删除它)
5). 用旧表原来的名字重命名新表
6). 根据需要,重新创建触发器、存储过程、索引和外键。
52. DROP TABLE tableName : 删除表没有确认,也不能撤销,执行这条语句将永久删除该表。
53. 视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
54. 视图本身不包含数据,因此返回的数据时从其他表中检索出来的。在添加或更改这些表中的数据时,视图将返回改变后的数据。
55. 因为视图不包含数据,所以每次使用视图时,都必须处理检索执行时需要的检索。如果你用多个联结和过滤创建了复杂的视图或者嵌套了视图,
性能可能会下降的很厉害。因为在部署视图的应用前,应该进行测试。
56. 有些DBMS把视图作为制度的查询,这表示可以从视图检索数据,但不能将数据写回底层表。
57. 视图的另外一种常见用途是已重新格式化检索出的数据。例如:concat (字段1,字段2) ; 还可以使用视图,过滤不想要的数据。
58. 事务用来管理INSERT、UPDATE、和 DETELE语句。
59. 在开始创建索引前,应该记住以下内容:
1). 索引改善检索操作的性能,但降低了数据插入、修改和删除的性能。在执行这些操作时,DBMS必须动态地更新索引。
2). 索引数据可能要占用大量的存储空间。
3). 并非所有数据都适合做索引。取值不多的数据(如州)不如具有更多可能值的数据(如姓或名),能通过索引得到那么多的好处。'
4). 索引用于数据过滤和数据排序。如果你经常以某种特定的顺序排序数据,则该数据可能适合做索引。'
5). 可以在索引中定义多个列(例如,州加上城市)。这样的索引仅在以州加城市的顺序排序时有用。如果想按城市排序,则这种索引没有用处。
60. 下面是触发器的一些常见用途。
1). 保证数据一致。例如,在INSERT或UPDATE操作中将所有州名转换为大写。
2). 基于某个表的变动在其他表上执行活动。例如,每当更新或删除一行时将审计跟踪记录写入某个日志表。
3). 进行额外的验证并根据需要回退数据。例如,保证某个顾客的可用资金不超限定,如果已经超出,则阻塞插入。
4). 计算计算列的值或更新时间戳。
61. MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:
1).数据库名与表名是严格区分大小写的;
2).表的别名是严格区分大小写的;
3).列名与列的别名在所有的情况下均是忽略大小写的;
4).变量名也是严格区分大小写的;
列名与列的别名在所有的情况下均是忽略大小写的。
表的别名是区分大小写的。下面的查询将不能工作,因为它用 a 和 A 引用别名:
mysql> SELECT col_name FROM tbl_name AS a WHERE a.col_name = 1 OR A.col_name = 2;
62. Mysql默认的字符检索策略:utf8_general_ci,表示不区分大小写;utf8_general_cs表示区分大小写,utf8_bin表示二进制比较,同样也区分大小写 。
(注意:在Mysql5.6.10版本中,不支持utf8_genral_cs!!!!)