SELECT
是一个特殊的关键字,它的语义是查询,取出结果。正则表达式
注意:仅为我的理解。数据库
FROM
子句,标识要查询的对象的来源,来源多是多个的。在查询有多个来源表的状况下,称之为联结查询(Join query
)。性能
最多见的常规写法是SELECT column FROM table
,表示从特定表取出全部行的特定列。优化
WHERE
子句用于过滤查询的行,只有知足条件的行会被查询出来。spa
常见的用法有SELECT column FROM table WHERE column <> 0
,表示在table
表中查询column
非空的行,返回这些行的column
。code
其中的二元关系运算符<>
表示不等于,其余常见的关系运算符还有这些。对象
运算符 | 含义 |
---|---|
= |
相等 |
> |
大于 |
< |
小于 |
>= |
大于等于 |
<= |
小于等于 |
!= |
不等于 |
<> |
不等于 |
此外还有一些SQL
关键字能够辅助编写判断逻辑。排序
SQL
关键字IN
能够用于判断元素是否在集合中。举例,SELECT 1 IN (1,2,3)
,查询1
是否在1,2,3
这个集合中。被判断的集合须要被小括号包围,而且以逗号分隔元素。索引
SQL
关键字BETWEEN
能够判断元素是否在必定区间中。举例,SELECT 1 BETWEEN 0 and 10
,查询1
是否在0
到10
的区间内。语法是BETWEEN [low] AND [high]
,区间较小的一端必须在左侧,较大的一端必须在右侧。开发
SQL
关键字LIKE
能够用很是简单的通配符来判断元素是否匹配必定的规则。举例,SELECT 'abcabcabc' LIKE '%CAB%'
,判断字符串abcabcabc
是否匹配%CAB%
。值得注意的是,模式串中的%
表明的是匹配0或任意多个字符,就像是正则表达式中的*
同样。此外还有_
,下划线,匹配1个任意字符。
MySQL
扩展的REGEXP
能够用正则表达式来匹配元素是否符合模式串。举例,SELECT 'abcabcabc' REGEXP '.*cab.*'
,正则表达式不作赘述,简单的模式串你们都会写。
ORDER BY
就像字面意义上说的那样,按照某个列来进行排序。举例来讲,我有一个学生表,记录了学号和姓名,我能够按照学号排序。
SELECT * FROM students ORDER BY id;
默认排序是升序,也能够经过指定DESC
或者ASC
来决定怎么排。ASC
是升序,DESC
是降序。
SELECT * FROM students ORDER BY id DESC;
AS
常见的用法是创建别名。
SELECT column AS id_alias FROM my_table AS table_alias WHERE table_alias.column <> 1;
这里出现了一个新的语法细节,table_alias.column
。用点.
链接表名和列名的行为相似于C++中的
typedef table_alias = my_table; auto id_alias = SELECT(table_alias::column, table_alias::column != 0);
看得出来,table_alias.column
是彻底限定了column
是哪一个column
,之因此有这种语法,是由于FROM
子句须要支持多个表做为查询来源。到时候可能就会用到table1.column <> 1 AND table2.column <> 2
这样的写法了。
而查询开头的column AS id_alias
则是标识查询结果列叫作id_alias
,举例如子查询的状况下,便于引用。
JOIN
的术语叫作联结,使用了JOIN
关键字的查询叫作联结查询。
联结查询和通常的查询不一样的地方是,联结查询的数据来源是多个表。
最简单的联结查询是内联结查询。
举例来讲,我如今有表students
以下,全部学生根据超能力开发等级分配到多个班级。
id | name | class |
---|---|---|
1 | stu1 | 1 |
2 | stu2 | 2 |
3 | stu3 | 3 |
4 | stu4 | 4 |
又有表top_class
,收录了全部接收高等级超能力者的班级,能进入这些班级的学生都是如同能考上985
、211
般恐怖如斯的存在。
id | name |
---|---|
1 | Lv 5 |
2 | Lv 4 |
3 | Lv 3 |
如今咱们要查询出学生中那些恐怖如斯的存在有哪些。
SELECT students.name AS name FROM students INNER JOIN top_class ON top_class.id = students.class;
语法JOIN [表] ON [条件]
也很简单啦。在例子中,JOIN
表示要联结表top_class
,ON
表示查询的对象要符合条件top_class.id = students.class
。很差理解?看看伪代码。
for(auto student : students) { // 先过滤 students 表自己,这个过滤应该由 WHERE 子句完成 for(auto cls : top_class) { // 而后联结表 top_class if(student.cls = cls.id) // 判断 ON students.class = top_class.id results.push(student); // 得出结果 } }
注意,伪代码的查询过程是错误的,为了方便理解 students.class = top_class.id 才这么写。真实数据库实现联结查询的方法应当查阅对应
DBMS
的文档。
注意的关键点有ON
很像但不一样于WHERE
,在了解LEFT JOIN
和RIGHT JOIN
时会区分。
LEFT JOIN
又叫左联结,基本思路是写在LEFT JOIN
左边的表知足条件便可做为结果,即便右边的表没有知足条件的条目。
仍是以上文的学园都市数据库为例(我tm写了什么…)
学生表 students
id | name | class |
---|---|---|
1 | stu1 | 1 |
2 | stu2 | 2 |
3 | stu3 | 3 |
4 | stu4 | 4 |
班级表 top_class
id | name |
---|---|
1 | Lv 5 |
2 | Lv 4 |
3 | Lv 3 |
如今咱们查询学生都处在哪些班级,获得班级的名字。
SELECT students.name as name, top_class.name as cls FROM students LEFT JOIN top_class ON top_class.id = students.class;
查询结果应该是这样子的。
name | cls |
---|---|
stu1 | Lv 5 |
stu2 | Lv 4 |
stu3 | Lv 3 |
stu4 | NULL |
注意到了吗?stu4
虽然不是top_class
的学生,可是仍是被查询出来了。
继续拿学园都市作例子……
实际上是和左联结一个鸟样。
SELECT students.name as name, top_class.name as cls FROM top_class RIGHT JOIN students ON top_class.id = students.class;
咱们注意到……我就是把 students
和 top_class
换了个位置。查询结果实际上是同样的。
name | cls |
---|---|
stu1 | Lv 5 |
stu2 | Lv 4 |
stu3 | Lv 3 |
stu4 | NULL |
交叉联结,查询结果是联结的表和FROM
的表的笛卡尔积,这么说听的明白不?听不明白就算了,由于交叉联结基本用不到。
其实就是把两个表的每一个行都排列组合一下:
术语叫自联结,其实也挺好理解的,直接举个例子看看。
id | name | class |
---|---|---|
1 | stu1 | 1 |
2 | stu2 | 1 |
3 | stu3 | 2 |
4 | stu4 | 2 |
注意我数据改了哈。
如今要查询出全部和stu1
同一个班级的学生。
通常咱们想怎么查?先查出stu1
是哪一个班级的:SELECT class FROM students WHERE name = 'stu1'
,而后查出全部属于这个班级的学生:SELECT name FROM students WHERE class = [上次查出来的班级]
。
那么…怎么写成一句话呢?
这时候自联结就能够上场了。
SELECT s1.id, s1.name, s1.class FROM students AS s1 INNER JOIN students AS s2 WHERE s1.class = s2.class AND s2.name = 'stu1';
查询结果是
id | name | class |
---|---|---|
1 | stu1 | 1 |
2 | stu2 | 1 |
基本思路是这样的:FROM
的表是s1
,所以INNER JOIN
查询结果来自s1
而不是s2
。查找s1
表中每一个行的class
在s2
表里有没有行具备一样的class
属性,同时,s2
具备和s1
一样class
属性的行还必须有个stu1
的name
。
分析得知,s2
中有stu1
这个name
的行只有1
,因此s2
表其实长这样。
id | name | class |
---|---|---|
1 | stu1 | 1 |
这时候再去看s1
表,s1
表的class
同时存在于s2
表的行只有1
和2
了。
其实OUTER JOIN
上面的LEFT JOIN
和RIGHT JOIN
已经讲过了,LEFT JOIN
的完整写法就是LEFT OUTER JOIN
,RIGHT JOIN
就是RIGHT OUTER JOIN
,和INNER JOIN
的区别在于OUTER JOIN
包含了指定表里不知足ON
条件的行。
这有个知识点,就是ON
条件不过滤指定OUTER JOIN
的表的不知足条件的行,可是WHERE
会过滤。
UNION
关键字的术语是联合查询。
做用是将多个SELECT
的结果放在一块儿并返回。
举个例子……咱们要查询全美最好的大学american_top_college
和中国最好的大学chinese_top_college
数据,来决定报考哪一个大学(反正都考不上),若是不想写成两句SELECT
,而后手工合并成一个表格的话,那么就用UNION
查询吧。
SELECT 'american' AS nation, american_top_college.name AS college_name, american_top_college.score_line AS score_line FROM american_top_college UNION SELECT 'china' AS nation, chinese_top_college.name AS college_name, chinese_top_college.score_line AS score_line;
查询结果…不展现了。
还有个细节可能要注意,若是有大学同时是美国大学和中国大学的话,那么为了在联合查询中排除相同的项目,可使用UNION ALL
而不是UNION
。
MySQL
支持一种实用的文本索引方式,叫作全文本搜索。你们都知道,正则表达式和简单通配符来查找文本是很是消耗性能的操做,并且难以优化(反正我想不出任何减小查询的优化思路)。MySQL
提供了全文本搜索的属性来帮助索引文本(可是想到中文支持我以为已经凉的差很少了),快速查询出包含特定词汇之类的行。
抱歉我以为不行。不说别的,中文分词就……
跳过了跳过了。