📄 06-4.html
字号:
<UL>
<LI><CODE>ESCAPED BY</CODE> 字符
<LI>在 <CODE>FIELDS TERMINATED BY</CODE> 中的第一个字符
<LI>在 <CODE>LINES TERMINATED BY</CODE> 中的第一个字符
</UL>
另外,<CODE>ASCII 0</CODE> 被转换到 <CODE>ESCAPED BY</CODE> 后而跟一个 0 (<CODE>ASCII 48</CODE>)。
上述行为的原因是,你<STRONG>必须</STRONG> 转义任何 <CODE>FIELDS TERMINATED BY</CODE>、<CODE>ESCAPED BY</CODE> 或<CODE>LINES TERMINATED BY</CODE> 字符,以便能可靠地将文件读回。<CODE>ASCII 0</CODE> 被转义是为了更容易地使用某些分页程序查看它。
因为结果文件并不需要遵从 SQL 句法,所以其它是不需要转义。
下面的例子得到的文件是可用于许多老程序的格式。
<PRE>
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM test_table;
</PRE>
<LI>
<A NAME="IDX1401"></A>
如果使用 <CODE>INTO DUMPFILE</CODE> 代替 <CODE>INTO OUTFILE</CODE>,MySQL 将在文件中只写一行,没任何列或行端接和任何转义。如果你希望存储一个 blob 列到文件中,这是非常有用的。
<LI>
注意,任何由 <CODE>INTO OUTFILE</CODE> 和 <CODE>INTO DUMPFILE</CODE> 创建的文件将被所有用户可读写!原因是,
MySQL 服务器不能够创建一个其他用户拥有的文件,(你决不应该以 root 身份运行 <CODE>mysqld</CODE>),该文件必须是公共可读写的,以便于你能操作它。
<P></P>
<LI>
如果你以页/行锁使用在一个存储引擎上 <CODE>FOR UPDATE</CODE>,被检索的记录行将被写锁。
</UL>
<H4><A NAME="JOIN"></A>6.4.1.1 <CODE>JOIN</CODE> 句法</H4>
<P>
<A NAME="IDX1402"></A>
<A NAME="IDX1403"></A>
<A NAME="IDX1404"></A>
<A NAME="IDX1405"></A>
<A NAME="IDX1406"></A>
<A NAME="IDX1407"></A>
<A NAME="IDX1408"></A>
<A NAME="IDX1409"></A>
<A NAME="IDX1410"></A>
<A NAME="IDX1411"></A>
<A NAME="IDX1412"></A>
<A NAME="IDX1413"></A>
</P>
<P>
MySQL 支持在 <CODE>SELECT</CODE> 中使用下面所示的 <CODE>JOIN</CODE> 句法:
</P>
<PRE>
table_reference, table_reference
table_reference [CROSS] JOIN table_reference
table_reference INNER JOIN table_reference join_condition
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference join_condition
table_reference LEFT [OUTER] JOIN table_reference
table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
{ OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr }
table_reference RIGHT [OUTER] JOIN table_reference join_condition
table_reference RIGHT [OUTER] JOIN table_reference
table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
</PRE>
<P>
<CODE>table_reference</CODE> 定义如下:
</P>
<A NAME="IDX1414"></A>
<PRE>
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
</PRE>
<P>
<CODE>join_condition</CODE> 定义如下:
</P>
<PRE>
ON conditional_expr |
USING (column_list)
</PRE>
<P>
通常不应该在 <CODE>ON</CODE> 存在任何条件式,它是用于限制在结果集中有哪个行的(对于这个规则也有例外)。如果你希望哪个记录行应该在结果中,你必须在 <CODE>WHERE</CODE> 子句中限制它。
</P>
<P>
注意,在早于 3.23.17 的版本中,<CODE>INNER JOIN</CODE> 不接受一个 <CODE>join_condition</CODE>!
</P>
<P>
<A NAME="IDX1415"></A>
<A NAME="IDX1416"></A>
上面所显示的最后一个 <CODE>LEFT OUTER JOIN</CODE> 句法仅仅是为了与 ODBC 兼容而存在的:
</P>
<UL>
<LI>
一个表引用可以使用 <CODE>tbl_name AS alias_name</CODE> 或 <CODE>tbl_name alias_name</CODE> 命以别名:
<PRE>
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
-> WHERE t1.name = t2.name;
</PRE>
<LI>
<CODE>ON</CODE> 条件是可以用在一个 <CODE>WHERE</CODE> 子句中的任何形式的条件。
<P></P>
<LI>
如果在一个 <CODE>LEFT JOIN</CODE> 的 <CODE>ON</CODE> 或 <CODE>USING</CODE> 部分中右表没有匹配的记录,一个所有列被设置为 <CODE>NULL</CODE> 的记录行将被用于右表。你可以通过这个行为找到一个表在另一个表中没有配对物的记录:
<PRE>
mysql> SELECT table1.* FROM table1
-> LEFT JOIN table2 ON table1.id=table2.id
-> WHERE table2.id IS NULL;
</PRE>
这个例子在 <CODE>table1</CODE> 中找到所有的记录行,其 <CODE>id</CODE> 值没有出现在 <CODE>table2</CODE> 中(即,所有在 <CODE>table1</CODE> 存在的,但在 <CODE>table2</CODE> 中没有对应记录的记录行)。当然,这是假定 <CODE>table2.id</CODE> 被声明为 <CODE>NOT NULL</CODE> 的。查看章节 <A HREF="manual1.html#LEFT_JOIN_optimisation">5.2.6 MySQL 如何优化 <CODE>LEFT JOIN</CODE> 和 <CODE>RIGHT JOIN</CODE></A>。
<P></P>
<LI>
<CODE>USING</CODE> <CODE>(column_list)</CODE> 子句指定了一个列的列表,列表的中列必须同时存在于两个表中。例如 <CODE>USING</CODE> 子句如下所示:
<PRE>
A LEFT JOIN B USING (C1,C2,C3,...)
</PRE>
它可以被定义为在语义上等同于一个这样的 <CODE>ON</CODE> 表达式:
<PRE>
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
</PRE>
<LI>
两个表的 <CODE>NATURAL [LEFT] JOIN</CODE> 被定义为在语义上等同于使用了 <CODE>USING</CODE> 子句指定存在于两张表中的所有列的一个 <CODE>INNER JOIN</CODE> 或一个 <CODE>LEFT JOIN</CODE>。
<P></P>
<LI>
<A NAME="IDX1417"></A>
<CODE>INNER JOIN</CODE> 和 <CODE>,</CODE> (逗号) 在语义上是等同的。都是在所有的表之间进行一个全联结。通常,在 WHERE 条件中指定表应该如何联结。
<P></P>
<LI>
<CODE>RIGHT JOIN</CODE> 作用类似于 <CODE>LEFT JOIN</CODE>。为了保持数据库边的代码上精简,<CODE>LEFT JOIN</CODE> 被推荐使用来代替 <CODE>RIGHT JOIN</CODE>。
<P></P>
<LI>
<A NAME="IDX1418"></A>
<CODE>STRAIGHT_JOIN</CODE> 等同于 <CODE>JOIN</CODE>,除了左表先于右表被读入。当联结优化器将表的顺序放错时(很少),这可用于这种情况。
<P></P>
<LI>
<A NAME="IDX1419"></A>
<A NAME="IDX1420"></A>
<A NAME="IDX1421"></A>
到 MySQL 3.23.12 时,当 MySQL 在从一个表中检索信息时,你可以提示它选择了哪一个索引。如果 <CODE>EXPLAIN</CODE> 显示 MySQL 使用了可能的索引列表中错误的索引,这个特性将是很有用的。通过指定 <CODE>USE INDEX (key_list)</CODE>,你可以告诉 MySQL 使用可能的索引中最合适的一个索引在表中查找记录行。可选的二选一句法 <CODE>IGNORE INDEX (key_list)</CODE> 可被用于告诉 MySQL 不使用特定的索引。
<A NAME="IDX1422"></A>
在 MySQL 4.0.9 中,你也可以使用 <CODE>FORCE INDEX</CODE>。这个有点像 <CODE>USE INDEX (key_list)</CODE>,但是有了这个附加物,一个表的扫描被采用时,将会有非常大的开销。换句法说,如果没有方法使用给定的索引在表中寻找记录行,这时表扫描才会被使用。
<A NAME="IDX1423"></A>
<A NAME="IDX1424"></A>
<CODE>USE/IGNORE/FORCE KEY</CODE> 分别是 <CODE>USE/IGNORE/FORCE INDEX</CODE> 的同义词。
</UL>
<P>
一些例子:
</P>
<PRE>
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id);
mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
-> LEFT JOIN table3 ON table2.id=table3.id;
mysql> SELECT * FROM table1 USE INDEX (key1,key2)
-> WHERE key1=1 AND key2=2 AND key3=3;
mysql> SELECT * FROM table1 IGNORE INDEX (key3)
-> WHERE key1=1 AND key2=2 AND key3=3;
</PRE>
<P>
查看章节 <A HREF="manual1.html#LEFT_JOIN_optimisation">5.2.6 MySQL 如何优化 <CODE>LEFT JOIN</CODE> 和 <CODE>RIGHT JOIN</CODE></A>。
</P>
<H4><A NAME="UNION"></A>6.4.1.2 <CODE>UNION</CODE> 句法</H4>
<P>
<A NAME="IDX1425"></A>
</P>
<PRE>
SELECT ...
UNION [ALL]
SELECT ...
[UNION
SELECT ...]
</PRE>
<P>
<CODE>UNION</CODE> 在 MySQL 4.0.0 中被实现。
</P>
<P>
<CODE>UNION</CODE> 用于将多个 <CODE>SELECT</CODE> 语句的结果联合到一个结果集中。
</P>
<P>
在 <CODE>SELECT</CODE> 中的 select_expression 部分列出的列必须具有同样的类型。第一个 <CODE>SELECT</CODE> 查询中使用的列名将作为结果集的列名返回。
</P>
<P>
<CODE>SELECT</CODE> 命令是一个普通的选择命令,但是有下列的限制:
</P>
<UL>
<LI>
只有最后一个 <CODE>SELECT</CODE> 命令可以有 <CODE>INTO OUTFILE</CODE>。
</UL>
<P>
如果你不为 <CODE>UNION</CODE> 使用关键词 <CODE>ALL</CODE>,所有返回的记录行将是唯一的,就好像你为整个返回集使用了一个 <CODE>DISTINCT</CODE>。如果你指定了 <CODE>ALL</CODE>,那么你将得到从所有使用的 <CODE>SELECT</CODE> 语句中返回的所有匹配记录行。
</P>
<P>
如果你希望对整个 <CODE>UNION</CODE> 结果使用一个 <CODE>ORDER BY</CODE>,你应该使用圆括号:
</P>
<PRE>
(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10)
ORDER BY a;
</PRE>
<P>
<A NAME="IDX1426"></A>
<H3><A NAME="HANDLER"></A>6.4.2 <CODE>HANDLER</CODE> 句法</H3>
<PRE>
HANDLER tbl_name OPEN [ AS alias ]
HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)
[ WHERE ... ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE ... ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE ... ] [LIMIT ... ]
HANDLER tbl_name CLOSE
</PRE>
<P>
<CODE>HANDLER</CODE> 语句提供了直接访问 <CODE>MyISAM</CODE> 表存储引擎的接口。
</P>
<P>
<CODE>HANDLER</CODE> 语句的第一个形式打开一个表,通过后来的 <CODE>HANDLER ... READ</CODE> 语句使它可读取。这个表对象将不能被其它线程共享,也不会被关闭,除非线程调用 <CODE>HANDLER tbl_name CLOSE</CODE> 或线程关闭。
</P>
<P>
第二个形式读取指定的索引遵从那个条件并且适合 <CODE>WHERE</CODE> 条件的一行(或更多的,由 <CODE>LIMIT</CODE> 子句指定)。
如果索引由几个部分组成(范围有几个列),值以逗号分隔的列表指定;如果只提供的一部分值,那么第一个列是必需的。
</P>
<P>
第三个形式从表中以索引的顺序读取匹配 <CODE>WHERE</CODE> 条件的一行(或更多的,由 <CODE>LIMIT</CODE> 子句指定)。
</P>
<P>
第四个形式(没有索引清单)从表中以自然的列顺序(在数据文件中存储的次序)读取匹配 <CODE>WHERE</CODE> 条件的一行(或更多的,由 <CODE>LIMIT</CODE> 子句指定)。如果期望做一个全表扫描,它将比 <CODE>HANDLER tbl_name READ index_name</CODE> 更快。
</P>
<P>
<CODE>HANDLER ... CLOSE</CODE> 关闭一个以 <CODE>HANDLER ... OPEN</CODE> 打开的表。
</P>
<P>
<CODE>HANDLER</CODE> 是一个稍微低级的语句。举例来说,它不提供一致性约束。更确切地说,<CODE>HANDLER ... OPEN</CODE> <STRONG>不</STRONG> 接受一个表的快照,并且 <STRONG>不</STRONG> 锁定表。这就意味着在一个 <CODE>HANDLER ... OPEN</CODE> 被执行后,表数据仍会被 (这个或其它的线程) 修改,这些修改可能在 <CODE>HANDLER ... NEXT</CODE> 和 <CODE>HANDLER ... PREV</CODE> 扫描中才会部分地出现。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -