一、
SELECT 语句的语法如下:
SELECT selection_list 选择哪些列
FROM table_list 从何处选择行
WHERE primary_constraint 行必须满足什么条件
GROUP BY grouping_columns 怎样对结果分组
HAVING secondary_constraint 行必须满足的第二条件
ORDER BY sorting_columns 怎样对结果排序
LIMIT count 结果限定
注意:所有使用的关键词必须精确地以上面的顺序给出。
除了词“SELECT”外,语法中的每样东西都是可选的。有的数据库还需要 FROM 子句。MySQL 有所不同,它允许对表达式求值而不引用任何表。
二、
SELECT最简单的形式是从一张表中检索每样东西:
mysql> SELECT * FROM pet;
你能从你的表中只选择特定的行。例如,如果想要找出end的记录:
mysql> SELECT * FROM pet WHERE name = "end";
也能从表中查出特定的列:
mysql> SELECT name, sex FROM student where age="25";
三、
在查询中可以加入表达式计算,来得到你想要的结果。例如得到end的身高与体重的乘积:
mysql> SELECT weight*height FROM pet WHERE name="end";
四、
可以用where与having进行条件查询,从而更精确的得到想要的记录。
另外,在字符串的比较中。通常对大小写是不敏感的、也就是说end与END的查询结果将是相同的。*表示所有。
可以用列名直接与一个对应类型的值对比:
mysql> SELECT * FROM student WHERE age>"20";
五、
运用and连接多个条件,为 和 的关系:
mysql> SELECT * FROM student WHERE age>"20" and sex="man";
同样有or,为 或 的关系:
mysql> SELECT * FROM student WHERE age>"20" or sex="man";
and 与 or 可以混用,但是最好加上括号来确定关系。
mysql> SELECT * FROM student WHERE (age>"20" and sex="man") or (age<"18" and sex="woman");
六、
可以用Order By来指定根据哪一列或者哪些列或者表达式来对结果进行排序。ASC为升序,默认。DESC为降序。
但是text和图片不能用来作为排序依据。
得到学生表中所有人的名字与性别,按年龄降序排列:
mysql> SELECT name, sex FROM student ORDER BY age DESC;
可以按多个列排序,但是有参考的优先级。
得到所有人的名字,先按年龄降序,年龄相同的按名字升序:
mysql> SELECT name FROM student ORDER BY age DESC , name;
七、
group by 指定结果根据哪一列进行分组。 与其他从句配合使用情况较多。
想知道每个同学有多少只笔:
mysql> SELECT student, COUNT(*) FROM pen GROUP BY student;
八、
当有需求时,可以连接多个表进行查询。或者将自己与自己连接。
mysql> SELECT student.name, (TO_DAYS(godate) - TO_DAYS(comedate))/365 AS time, sex
FROM student, time WHERE student.name = time.name;
与自己连接:
mysql> SELECT p1.age, p1.sex, p2.age, p2.sex FROM student AS p1, student AS p2
-> WHERE p1.age = p2.age AND p1.sex = "woman" AND p2.sex = "man";
=============================================
一、几种联结方式
1.等值联结(内联结):等值联结,顾名思义,基于两个表之间的相等测试,又称内部联结。
eg: SELECT name, age, num FROM student, school WHERE student.name = school.name;
更推荐的联结写法是:SELECT name, age, num FROM student INNER JOIN school ON student.name = school.name;
2.自连接:在同一张表中的联结关系
eg:在student表中,某学生s1的成绩很突出,他的老师是t1,现在想找出t1的其他学生,看看是否都很牛x。
SELECT name, age FROM student WHERE teacher = (SELECT teacher from student where name = 's1');
更推荐的联结写法是:
SELECT stu1.name, stu1.age FROM student AS stu1, student AS stu2 WHERE stu1.teacher = stu2.teacher AND stu2.name = 's1';
3.自然连接:标准的联结返回所有数据,甚至相同的列出现多次。自然连接排除重复出现,同一列只出现一次。但是这一工作不是由mysql完成,是有指令下达者自己完成的。大多时候我们的联结都是自然连接,不是自然连接的情况很少能用到。通配符最多只对同一个表使用,其他的表的列要明确列出条件。
4.外部联结:联结是将一个表中的行与其他表的行相关联。但是有的时候们需要包含没有关联行的那些行。例如,统计每个学生期末成绩,包括那些没有参加考试的学生。这种类型的联结,叫做外部联结。
内部链接的写法是:SELECT student.name, exam.score FROM student INNER JOIN exam ON student.sid = exam.sid;
外部联结的写法是:SELECT student.name, exam.score FROM student LEFT OUTER JOIN exam ON student.sid = exam.sid;
差别在于外部联结包含没有关联的行。使用外部联结的时候,必须用LEFT或RIGHT指定包括其所有行的表。使用了LEFT表示包含OUTER JOIN左边的表的所有行。
二、别名
可以利用AS为表、结算结果等起别名。
eg:SELECT name, age, num FROM student AS s, school AS sc WHERE s.name = sc.name;
三、拼接字段
利用Concat()将值联结到一起构成单个值。
eg:SELECT Concat(name, ' : ', age) FROM student WHERE sex = 'm';
RTrim()去掉串右边的空格, LTrim()去掉左边空格, Trim()去掉两侧空格。
四、组合查询:UNION允许将多个查询结果作为单个结果集返回。也称复合查询。
UNION的规则:
1.必须由两条或两条以上的SELECT组成。
2.每个SELECT必须包含相同的列、表达式、聚集函数,可以不同顺序
3.列类型数据必须兼容。不比完全相同,但是可隐式转换为相同类型
4.ORDER BY只能出现一次,且必须出现在最后一条语句中
eg:SELECT sid, age, sex FROM student WHERE age <= 20 UNION SELECT sid, age, sex FROM student WHERE sex = 'm';
例子中,UNION用于同一个表的多个查询。它也可以用于不同表的多个查询。
UNION默认是去除结果集中重复的行,只保留一行。如果想不去重,那么用UNION ALL关键字即可,用法与UNION相同。
五、全文本搜索
并不是所有引擎都支持全文本搜索,应用前需确定你的数据库引擎支持它。例如:MyISAM。
虽然利用LIKE关键字和正则表达式可以进行很复杂的模式匹配,但是它们有一些限制。
1.性能问题。通配符和正则表达式会尝试匹配表中的所有行,当数据量很大时,这无疑是非常耗时的。
2.准确性问题。通过正则表达式很难表达准确什么想要匹配,什么不匹配。
3.智能化问题。通配符和正则表达式不能提供一种智能化的选择结果。例如,一个特殊词的搜索无法找出不包含这个词,但是包含相关词的行。
这些问题,都可以用全文本搜索来解决。它不需要对每一行、每一个词都进行分析处理。MySQL会建立一个指定列中各词的一个索引,搜索可以针对这些词进行。在创建表的时候,可以FULLTEXT指定被索引的列。也可以对现有表指定。
eg:CREATE TABLE student
(
sid int NOT NULL AUTO_INCREMENT,
name char(10) NOT NULL,
address text NULL,
PRIMARY KEY(sid),
FULLTEXT(address)
)TYPE = MyISAM;
MySQL在创建表后会自动维护这个索引,在增加、删除、修改后会自动更新。在表结构有修改时,会重新进行索引。
创建索引是需要时间的,所以在大量导入数据的时候最好先把FULLTEXT关掉,导入后再进行索引。以便快速导入数据,而且索引的时间是要小于导入数据时每导入一行索引一次的总时间的。
在索引后使用MATCH和Against执行全文搜索。MATCH指定搜索的列,Against指定要使用搜索表达式。
eg:SELECT sid, name FROM student WHERE MATCH(address) Against('beijing');
MATCH()返回的结果中,必须包含和Against指定的完全相同的值。全文本搜索不区分大小写,除非使用BINARY方式。全文本搜索对结果是有排序的。匹配度更高的结果会排序更靠前。例如两行中均又一次被搜索关键词出现,但是行a中出现的位置比行b中位置更靠前,则a行匹配度更高,在结果中行a的位置会更靠前。
全文搜索也可以作为计算字段用在SELECT中,它将返回所有行,返回值是每一行的匹配等级值。匹配度越高,等级值越大。没有关键词出现的等级值为0.
eg:SELCET sid, MATCH(address) Against('beijing') AS rank FROM student;
全文搜索的查询扩展。利用查询扩展不止找到关键词出现的行,还可以找到相关结果,即时它们不准确包含查找的词。
eg:SELECT sid, name FROM student WHERE MATCH(address) Against('beijing' WITH QUERY EXPANSION);
实际上扩展查询,MySQL是执行了两遍全文本搜索。第一次是搜索包含关键词的行,然后找到行中其他相对重要的词,第二次查询,是搜索包含关键词和第一次找到的那些“相对重要的词”的行。当数据越多,行越多时,扩展查询的效果越好。
布尔文本搜索
布尔文本搜索可以提供更多的细节内容,例如要匹配的词、要排斥的词、关键词的优先级、表达式分组等等。
布尔文本搜索在没有FULLTEXT索引时也可以使用。但这是非常缓慢的操作,而且性能会随着数据量的增加而降低。
eg:SELECT sid, name FROM student WHERE MATCH(address) Against('beijing -chaoyang*' IN BOOLEAN MODE);
这个例子中,要匹配的词是beijing,‘-’表示排斥,也就是排除掉包含以chaoyang开头的所有词。(在mysql4.x版本中,不能用通配符*,要写成-chaoyangs。)
几个布尔操作符的意义:‘+’包含;‘-’排斥; ‘>'包含且增加优先级; '<'包含但减少优先级; ’()‘把词组成子表达式,可以把表达式作为一个词来用操作符修饰; ’*‘词尾通配符, ’“”‘双引号定义一个短语,可以对短语进行操作符修饰。(布尔搜索方式返回的结果不按等级值排序)
全文本搜索由几个特点:
1.全文本搜索时,短词将被从索引中排除。短词定义为具有3个或以下字符的词。这个数目可以更改。
2.全文本搜索忽略单引号,如don't索引为dont。
3.Mysql有一个内用的词列表,这些词是被索引忽略的,如果需要,列表可以被覆盖。
4.如果一个词出现在50%以上的行中,则这个词被当做非用词汇忽略。这条规则不用于IN BOOLEAN MODE中。