内容导航

  • 条件查询
  • = 【等于】
  • <> != 【不等于】
  • < 小于 <= 小于等于 > 大于 >= 大于等于
  • BETWEEN AND 两个值之间,>= AND <=
  • 使用is[IS]来衡量空null
  • 使用IS NOT 来衡量不为空
  • AND OR NOT 或 且 非 逻辑连接词
  • AND 和 OR的优先级问题
  • IN 【NOT IN】 相当于多个OR,在范围内
  • LIKE % _ 模糊查询
  • 如何查询名字中带有_的?
  • 排序 ORDER BY
  • 如何降序?DESC
  • 指定升序 ASC
  • 多字段排序 【, 先排前,相等再排后】
  • 排序可不写字段名,可写字段的位置
  • 数据处理函数【单行处理函数】
  • LOWER(col_name) UPPER(col_name)
  • substr(str,startpos,length)

MySQL数据库条件查询(模糊查询),查询时排序,数据处理函数

之前的简单查询知道了简单查询字段,以及为字段起别名,同时了解字段时可以使用数学表达式

条件查询

条件查询只是查询符合条件的数据,而不是所有的数据,因为数据过于庞大,这个时候要查询有用的信息才可以

条件查询的语句格式为

>SELECT col_name
>FROM table_name
>WHERE  condition;     //遇到分号才结束,所以一般换行可以使结构更清晰

= 【等于】

  • 这里的等号不只是数学上的等号,就是整型和浮点型;字符串类型也是可以的

比如这里我们可以就使用name = ‘queryname’来查询想要的结果

mysql> SELECT * FROM fruits WHERE fruits_name = '苹果';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
1 row in set (0.00 sec)

因为colum是可以直接进行数学运算的,所以这里的等于就是数学上的等于,不是程序上的等于==,使用的格式是

SELECT col_name1,col_name2 FROM table_name WHERE col_name = ……;

后面的条件字段不一定出现在前面的查询字段中

mysql> SELECT fruits_name AS '水果名称',fruits_origin '产地',fruits_remark '水果品牌' FROM fruits WHERE fruits_price = 6;
+----------+------+----------+
| 水果名称 | 产地 | 水果品牌 |
+----------+------+----------+
| 香蕉     | 海南 | 小芭蕉   |
+----------+------+----------+
1 row in set (0.00 sec)

<> != 【不等于】

既然有等于,那就有不等于了,不等于就是除了等于之外的所有的数据,这里有两种表示方式,第一种就是程序语言中的 !=,另外的一个就是<>,为啥这个也可以,这个不是括号,不是java中的泛型符号,而是数学含义上面的大于和小于,又大于的又小于的,那不就是不等于了嘛

SELECT col_name1,col_name2,col_name3…… FROM table_name WHERE col <> x;

SELECT col_name1,col_name2,col_name3…… FROM table_name WHERE col != x;

这里也举一个例子

mysql> SELECT * FROM fruits;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
//原本是这个样子的,现在查询不等于6的
mysql> SELECT * FROM fruits WHERE fruits_price <> 6;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

和预想的是一样的,就是价格不等于6的都是满足条件的,都会查询到,这里为了书写的时间就使用的*来查询的所有的字段

< 小于 <= 小于等于 > 大于 >= 大于等于

这还是简单的数学比较,意思就是数学上的意思,格式和上面一样,就是改变条件就可以了,这里就简单举个例子就好了

mysql> SELECT * FROM fruits WHERE fruits_price < 6;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

BETWEEN AND 两个值之间,>= AND <=

这里between and是包含边界值的,就是位于两者之间的都是

<= AND >= 是程序中的表达方式

mysql> SELECT * FROM fruits WHERE fruits_price >= 3.7 AND fruits_price <= 6;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

再看一下between的表示

mysql> SELECT * FROM fruits WHERE fruits_price BETWEEN 3.7 AND 6;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

使用时遵循左小右大,闭区间,包括两端的值

使用is[IS]来衡量空null

在程序中null也是一个值,比如赋值的时候就会给右边赋值null,但是数据库中不能使用=来判断空,因为数据库中的null代表什么也没有,它不是一个值

SELECT col_name …… FROM table_name WHERE col IS null;

这里可以看一下使用方式

mysql> SELECT * FROM fruits WHERE fruits_name IS null;
Empty set (0.00 sec)

因为创建的时候没有空的部分,所以查不出来

使用IS NOT 来衡量不为空

既然is 可以衡量为空,那么is not也就可以判断不为空的部分了

SELECT col_name …… FROM table_name WHERE col IS NOT null;

看一下效果

mysql> SELECT * FROM fruits WHERE fruits_name IS NOT  null;
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
3 rows in set (0.00 sec)

AND OR NOT 或 且 非 逻辑连接词

不管是什么语言,都离不开逻辑连接词,mysql中或且非就是and or not 程序中是&& || !

and 可以并列多个条件,多个条件同时成立才成立

or 关联的几个条件只要右一个成立就OK

not就是取反

上面都已经使用过,这里就简单举个例子

mysql> SELECT * FROM fruits WHERE fruits_price >= 2.8 AND fruits_name = '雪 梨';
Empty set (0.00 sec)

mysql>  SELECT * FROM fruits WHERE fruits_price >= 2.8 OR  fruits_name = '雪 梨';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
3 rows in set (0.00 sec)

AND 和 OR的优先级问题

需要注意的是,数据库中and的优先级比or高,所以要正确的表示一个逻辑是需要加上括号的

这里语句很长就写成多行了

mysql> SELECT
    -> fruits_name '水果名称',fruits_price AS '水果价格',fruits_origin '水果产地',fruits_remark '水果品牌'
    -> FROM
    -> fruits
    -> WHERE
    -> (fruits_price BETWEEN 2.8 AND 6) AND (fruits_name = '苹果' OR fruits_name = '香蕉');
+----------+----------+----------+----------+
| 水果名称 | 水果价格 | 水果产地 | 水果品牌 |
+----------+----------+----------+----------+
| 苹果     |      2.8 | 山东     | 红富士   |
| 香蕉     |        6 | 海南     | 小芭蕉   |
+----------+----------+----------+----------+
2 rows in set (0.00 sec)

容易犯的错误是书写是单词还有就是括号一定要匹配

IN 【NOT IN】 相当于多个OR,在范围内

使用IN时需要注意的是使用括号将OR需要连接的部分括起来,里面是一系列的孤立的值,不代表范围,如果是字符串,需要加单引号

NOT IN就是范围之外的

mysql> SELECT * FROM fruits WHERE fruits_name IN('苹果','香蕉');
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
| 1003 | 香蕉        |            6 | 海南          | 小芭蕉        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM fruits WHERE fruits_name NOT  IN('苹果','香蕉');
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
+------+-------------+--------------+---------------+---------------+
1 row in set (0.00 sec)

IN就相当于是多个or =

fruits_name IN(‘苹果’,‘香蕉’) 等价于 fruits_name = ‘香蕉’ OR fruits_name = ‘苹果’;

LIKE % _ 模糊查询

在实际运用中我们有的时候总是需要支持模糊查询的,在MySQL数据库中,就使用like关键字来表示模糊查询

  • %是一个特殊的符号,%匹配任意多个字符
  • _ 也是一个特殊符号,_匹配任意一个字符
//查询的格式
SELECT col_name…… FROM table_name WHERE col LIKE 7%6;

注意查询的时候,LIKE 还是和IN,BETWEEN一样,代表的是=

比如这里就是col = 7%6; 只是这里%替代了中间的任意字符

所以如果匹配的是字符串,还是要记得加单引号

mysql> SELECT * FROM fruits WHERE fruits_name LIKE '%果';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM fruits WHERE fruits_name LIKE '_果';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
1 row in set (0.00 sec)

这里就是模糊查询名字中带‘果’字的

mysql> SELECT * FROM fruits WHERE fruits_remark LIKE '%红%';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

mysql>  SELECT * FROM fruits WHERE fruits_remark LIKE '红_';
Empty set (0.00 sec)

mysql>  SELECT * FROM fruits WHERE fruits_remark LIKE '红%';
+------+-------------+--------------+---------------+---------------+
| id   | fruits_name | fruits_price | fruits_origin | fruits_remark |
+------+-------------+--------------+---------------+---------------+
| 1001 | 葡萄        |          3.7 | 山东          | 红香妃        |
| 1002 | 苹果        |          2.8 | 山东          | 红富士        |
+------+-------------+--------------+---------------+---------------+
2 rows in set (0.00 sec)

这里就可以看出_只能代表一个字符,所以第二项查询没有任何结果,第一项是查询有红字的,第三个查询红在第一个位置的

如何查询名字中带有_的?

上面已经说过_ 是特殊字符,那就不能使用%_%来查询了

参照程序中的表达方式,这里就可以使用转义字符\来表达

SELECT col_name…… FROM table_name WHERE col LIKE '%\_%';

排序 ORDER BY

之前提到的查询手段中有查询某个字段,查询满足某种条件的数据,还有查询的列进行数学运算,和模糊查询,有的时候的可能还需要对查询结果进行排序

这里使用关键字ORDER BY col就是按照某个字段进行升序排序

SELECT col_name…… FROM table_name ORDER BY col;

昨天的博客中已经为大家看了world数据库的city表,里面的数据

4079 rows in set (0.03 sec)

还是挺多的,里面的数据有ID,Name,CountryCode,District,Population

这里先来复习一下,我们这里截取前30个数据

mysql> SELECT * FROM city WHERE ID <= 30;
+----+------------------+-------------+---------------+------------+
| ID | Name             | CountryCode | District      | Population |
+----+------------------+-------------+---------------+------------+
|  1 | Kabul            | AFG         | Kabol         |    1780000 |
|  2 | Qandahar         | AFG         | Qandahar      |     237500 |
|  3 | Herat            | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif   | AFG         | Balkh         |     127800 |
|  5 | Amsterdam        | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam        | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag             | NLD         | Zuid-Holland  |     440900 |
|  8 | Utrecht          | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven        | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg          | NLD         | Noord-Brabant |     193238 |
| 11 | Groningen        | NLD         | Groningen     |     172701 |
| 12 | Breda            | NLD         | Noord-Brabant |     160398 |
| 13 | Apeldoorn        | NLD         | Gelderland    |     153491 |
| 14 | Nijmegen         | NLD         | Gelderland    |     152463 |
| 15 | Enschede         | NLD         | Overijssel    |     149544 |
| 16 | Haarlem          | NLD         | Noord-Holland |     148772 |
| 17 | Almere           | NLD         | Flevoland     |     142465 |
| 18 | Arnhem           | NLD         | Gelderland    |     138020 |
| 19 | Zaanstad         | NLD         | Noord-Holland |     135621 |
| 20 | ?s-Hertogenbosch | NLD         | Noord-Brabant |     129170 |
| 21 | Amersfoort       | NLD         | Utrecht       |     126270 |
| 22 | Maastricht       | NLD         | Limburg       |     122087 |
| 23 | Dordrecht        | NLD         | Zuid-Holland  |     119811 |
| 24 | Leiden           | NLD         | Zuid-Holland  |     117196 |
| 25 | Haarlemmermeer   | NLD         | Noord-Holland |     110722 |
| 26 | Zoetermeer       | NLD         | Zuid-Holland  |     110214 |
| 27 | Emmen            | NLD         | Drenthe       |     105853 |
| 28 | Zwolle           | NLD         | Overijssel    |     105819 |
| 29 | Ede              | NLD         | Gelderland    |     101574 |
| 30 | Delft            | NLD         | Zuid-Holland  |      95268 |
+----+------------------+-------------+---------------+------------+
30 rows in set (0.01 sec)

比如现在要对这30条数据按照人口数量升序排列

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID <= 30
    -> ORDER BY
    -> Population;
+----+------------------+-------------+---------------+------------+
| ID | Name             | CountryCode | District      | Population |
+----+------------------+-------------+---------------+------------+
| 30 | Delft            | NLD         | Zuid-Holland  |      95268 |
| 29 | Ede              | NLD         | Gelderland    |     101574 |
| 28 | Zwolle           | NLD         | Overijssel    |     105819 |
| 27 | Emmen            | NLD         | Drenthe       |     105853 |
| 26 | Zoetermeer       | NLD         | Zuid-Holland  |     110214 |
| 25 | Haarlemmermeer   | NLD         | Noord-Holland |     110722 |
| 24 | Leiden           | NLD         | Zuid-Holland  |     117196 |
| 23 | Dordrecht        | NLD         | Zuid-Holland  |     119811 |
| 22 | Maastricht       | NLD         | Limburg       |     122087 |
| 21 | Amersfoort       | NLD         | Utrecht       |     126270 |
|  4 | Mazar-e-Sharif   | AFG         | Balkh         |     127800 |
| 20 | ?s-Hertogenbosch | NLD         | Noord-Brabant |     129170 |
| 19 | Zaanstad         | NLD         | Noord-Holland |     135621 |
| 18 | Arnhem           | NLD         | Gelderland    |     138020 |
| 17 | Almere           | NLD         | Flevoland     |     142465 |
| 16 | Haarlem          | NLD         | Noord-Holland |     148772 |
| 15 | Enschede         | NLD         | Overijssel    |     149544 |
| 14 | Nijmegen         | NLD         | Gelderland    |     152463 |
| 13 | Apeldoorn        | NLD         | Gelderland    |     153491 |
| 12 | Breda            | NLD         | Noord-Brabant |     160398 |
| 11 | Groningen        | NLD         | Groningen     |     172701 |
|  3 | Herat            | AFG         | Herat         |     186800 |
| 10 | Tilburg          | NLD         | Noord-Brabant |     193238 |
|  9 | Eindhoven        | NLD         | Noord-Brabant |     201843 |
|  8 | Utrecht          | NLD         | Utrecht       |     234323 |
|  2 | Qandahar         | AFG         | Qandahar      |     237500 |
|  7 | Haag             | NLD         | Zuid-Holland  |     440900 |
|  6 | Rotterdam        | NLD         | Zuid-Holland  |     593321 |
|  5 | Amsterdam        | NLD         | Noord-Holland |     731200 |
|  1 | Kabul            | AFG         | Kabol         |    1780000 |
+----+------------------+-------------+---------------+------------+
30 rows in set (0.00 sec)

可以看到已经按照人口的数量从小到大排序完成了

只是需要注意这里查询的逻辑时先截取前30个再排序,所以WHERE在前,ORDER BY在后

ORDER BY 默认时升序

如何降序?DESC

上面已经知道ORDER BY默认时升序,那如何降序呢

降序就只需要在排序字段后面加上DESC关键字就可以了

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID <= 30
    -> ORDER BY
    -> Population DESC;
+----+------------------+-------------+---------------+------------+
| ID | Name             | CountryCode | District      | Population |
+----+------------------+-------------+---------------+------------+
|  1 | Kabul            | AFG         | Kabol         |    1780000 |
|  5 | Amsterdam        | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam        | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag             | NLD         | Zuid-Holland  |     440900 |
|  2 | Qandahar         | AFG         | Qandahar      |     237500 |
|  8 | Utrecht          | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven        | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg          | NLD         | Noord-Brabant |     193238 |
|  3 | Herat            | AFG         | Herat         |     186800 |
| 11 | Groningen        | NLD         | Groningen     |     172701 |
| 12 | Breda            | NLD         | Noord-Brabant |     160398 |
| 13 | Apeldoorn        | NLD         | Gelderland    |     153491 |
| 14 | Nijmegen         | NLD         | Gelderland    |     152463 |
| 15 | Enschede         | NLD         | Overijssel    |     149544 |
| 16 | Haarlem          | NLD         | Noord-Holland |     148772 |
| 17 | Almere           | NLD         | Flevoland     |     142465 |
| 18 | Arnhem           | NLD         | Gelderland    |     138020 |
| 19 | Zaanstad         | NLD         | Noord-Holland |     135621 |
| 20 | ?s-Hertogenbosch | NLD         | Noord-Brabant |     129170 |
|  4 | Mazar-e-Sharif   | AFG         | Balkh         |     127800 |
| 21 | Amersfoort       | NLD         | Utrecht       |     126270 |
| 22 | Maastricht       | NLD         | Limburg       |     122087 |
| 23 | Dordrecht        | NLD         | Zuid-Holland  |     119811 |
| 24 | Leiden           | NLD         | Zuid-Holland  |     117196 |
| 25 | Haarlemmermeer   | NLD         | Noord-Holland |     110722 |
| 26 | Zoetermeer       | NLD         | Zuid-Holland  |     110214 |
| 27 | Emmen            | NLD         | Drenthe       |     105853 |
| 28 | Zwolle           | NLD         | Overijssel    |     105819 |
| 29 | Ede              | NLD         | Gelderland    |     101574 |
| 30 | Delft            | NLD         | Zuid-Holland  |      95268 |
+----+------------------+-------------+---------------+------------+
30 rows in set (0.00 sec)

这里的DESC关键字和之前查询表的基本结构的DESCRIBE的简写DESC是相同的

指定升序 ASC

既然指定降序都有关键字,那么就有指定升序了,指定升序的关键字是ASC,但是因为不加关键字默认就是升序,所以没有必要

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID < 15
    -> ORDER BY
    -> Population ASC;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
| 14 | Nijmegen       | NLD         | Gelderland    |     152463 |
| 13 | Apeldoorn      | NLD         | Gelderland    |     153491 |
| 12 | Breda          | NLD         | Noord-Brabant |     160398 |
| 11 | Groningen      | NLD         | Groningen     |     172701 |
|  3 | Herat          | AFG         | Herat         |     186800 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
|  1 | Kabul          | AFG         | Kabol         |    1780000 |
+----+----------------+-------------+---------------+------------+
14 rows in set (0.00 sec)

多字段排序 【, 先排前,相等再排后】

有的时候两个字段的某项排序的值是相同的,比如学校排名的时候,如果分数相等,就按照名字来排

多字段排序使用逗号隔开,前面的先排序,只有前面的相等的时候才会轮到后面的排序

//这里按照CountryCode来进行排列
mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID < 15
    -> ORDER BY
    -> CountryCode ASC;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  1 | Kabul          | AFG         | Kabol         |    1780000 |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
| 11 | Groningen      | NLD         | Groningen     |     172701 |
| 12 | Breda          | NLD         | Noord-Brabant |     160398 |
| 13 | Apeldoorn      | NLD         | Gelderland    |     153491 |
| 14 | Nijmegen       | NLD         | Gelderland    |     152463 |
+----+----------------+-------------+---------------+------------+
14 rows in set (0.00 sec)

字符串排序是先比较字符串第一个字符的大小。而不是像int型比较整个数字的大小

所以这里就是先按照第一个字母进行比较,A在N前面,再比较后面的字母,直到最后

那么这里如果想在countrycode相同的时候再按照人口升序排列怎么办?

ORDER BY CountryCode ASC,Population ASC;

看一下效果

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID < 15
    -> ORDER BY
    -> CountryCode ASC,Population ASC;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  1 | Kabul          | AFG         | Kabol         |    1780000 |
| 14 | Nijmegen       | NLD         | Gelderland    |     152463 |
| 13 | Apeldoorn      | NLD         | Gelderland    |     153491 |
| 12 | Breda          | NLD         | Noord-Brabant |     160398 |
| 11 | Groningen      | NLD         | Groningen     |     172701 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
+----+----------------+-------------+---------------+------------+
14 rows in set (0.00 sec)

排序可不写字段名,可写字段的位置

比如上面的按照Population升序,因为Population是第5列,所以就可以换成5;

数据库中位置是从1开始的

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID < 15
    -> ORDER BY
    -> 3 ASC,5 ASC;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  1 | Kabul          | AFG         | Kabol         |    1780000 |
| 14 | Nijmegen       | NLD         | Gelderland    |     152463 |
| 13 | Apeldoorn      | NLD         | Gelderland    |     153491 |
| 12 | Breda          | NLD         | Noord-Brabant |     160398 |
| 11 | Groningen      | NLD         | Groningen     |     172701 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
+----+----------------+-------------+---------------+------------+
14 rows in set (0.00 sec)

所以这种写法提供了一种方便的手段,只是要注意字段的位置不要弄错了,特别是使用DDL语句改变了结构之后,这种写法不健壮,开发中不提倡

这里再强调一下关键字的顺序,where是再order之前,也就是 SELECT FROM WHERE ORDER BY

排序是再最后,执行的顺序就是from 之后 where 再select之后再排序

当顺序写错了,会报错的

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> ORDER BY
    -> Population
    -> WHERE
    -> ID <= 30;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE
ID <= 30' at line 7

总结一下就是先截取再排序,排序总是在最后

数据处理函数【单行处理函数】

之前已经分享了使用数学运算来简单处理数据,比如fruits_price + 3,还有一些乘法之类的,但是程序的库中都有很多函数,mysql中也提供了很多处理函数

数据处理函数又叫做单行处理函数,与多行处理函数【分组函数】相互对应,单行处理函数的特点是一个输入对应一个输出

单行处理函数就是以行为单位处理,也就是一个row就可以对应一个输出,处理一行之后才能处理下一行,而多行处理函数是多个输入【多行row】对应一个输出,比如求和函数sum,最大值max,这都是很多行才输出的一个结果;比如一行就没有最大值和求和的意义

单行处理函数常见的有 【trim —修剪 】 去空格

• Lower 转换小写
• upper 转换大写
• substr 取子串(substr(被截取的字符串,起始下标,截取的长度))
• length 取长度
• trim 去空格
• str_to_date 将字符串转化为日期
• format 设置千分位
• round 四舍五入
• rand() 生成随机数
• ifnull 可以将null转化为一个具体的值

LOWER(col_name) UPPER(col_name)

该单行处理函数可以一行一行地将某个字段地字符串全部转换为小写,当然配合SELECT,是不会改变原数据地

同时和之前的数学运算一样,处理之后,显示地表名也会自带将处理函数写入,可以使用起别名地方式来解决

SELECT LOWER(col_name) FROM table_name;
SELECT col+3  FROM table_name;  //两者具有相似之处

这里可以在world数据库中地city表中尝试

mysql> SELECT
    -> *
    -> FROM
    -> city
    -> WHERE
    -> ID <= 10;
+----+----------------+-------------+---------------+------------+
| ID | Name           | CountryCode | District      | Population |
+----+----------------+-------------+---------------+------------+
|  1 | Kabul          | AFG         | Kabol         |    1780000 |
|  2 | Qandahar       | AFG         | Qandahar      |     237500 |
|  3 | Herat          | AFG         | Herat         |     186800 |
|  4 | Mazar-e-Sharif | AFG         | Balkh         |     127800 |
|  5 | Amsterdam      | NLD         | Noord-Holland |     731200 |
|  6 | Rotterdam      | NLD         | Zuid-Holland  |     593321 |
|  7 | Haag           | NLD         | Zuid-Holland  |     440900 |
|  8 | Utrecht        | NLD         | Utrecht       |     234323 |
|  9 | Eindhoven      | NLD         | Noord-Brabant |     201843 |
| 10 | Tilburg        | NLD         | Noord-Brabant |     193238 |
+----+----------------+-------------+---------------+------------+
10 rows in set (0.00 sec)

mysql> SELECT
    -> ID,Name,LOWER(CountryCode),District,Population
    -> FROM
    -> city
    -> WHERE
    -> ID <= 10;
+----+----------------+--------------------+---------------+------------+
| ID | Name           | LOWER(CountryCode) | District      | Population |
+----+----------------+--------------------+---------------+------------+
|  1 | Kabul          | afg                | Kabol         |    1780000 |
|  2 | Qandahar       | afg                | Qandahar      |     237500 |
|  3 | Herat          | afg                | Herat         |     186800 |
|  4 | Mazar-e-Sharif | afg                | Balkh         |     127800 |
|  5 | Amsterdam      | nld                | Noord-Holland |     731200 |
|  6 | Rotterdam      | nld                | Zuid-Holland  |     593321 |
|  7 | Haag           | nld                | Zuid-Holland  |     440900 |
|  8 | Utrecht        | nld                | Utrecht       |     234323 |
|  9 | Eindhoven      | nld                | Noord-Brabant |     201843 |
| 10 | Tilburg        | nld                | Noord-Brabant |     193238 |
+----+----------------+--------------------+---------------+------------+
10 rows in set (0.00 sec)

确实转成了小写,大写地UPPER是相同地用法,使用取别名来让显示地字段名消去函数名

substr(str,startpos,length)

取子串还是很有需求地,比如月份就是每个单词地前3个字母大写,只是注意格式,str就是字段名,startpos就是开始位置,length就是结束位置

只是需要注意地一点,上面已经提到过一次了

Mysql中的计数都是从1开始的,不管是上面的位置,还是这里的起始位置

//substr就是下标最小为1,为0就截取错误为空
mysql> SELECT
    -> ID,UPPER(SUBSTR(Name,1,3)),CountryCode,District,Population
    -> from
    -> city
    -> WHERE
    -> ID <= 10;
+----+-------------------------+-------------+---------------+------------+
| ID | UPPER(SUBSTR(Name,1,3)) | CountryCode | District      | Population |
+----+-------------------------+-------------+---------------+------------+
|  1 | KAB                     | AFG         | Kabol         |    1780000 |
|  2 | QAN                     | AFG         | Qandahar      |     237500 |
|  3 | HER                     | AFG         | Herat         |     186800 |
|  4 | MAZ                     | AFG         | Balkh         |     127800 |
|  5 | AMS                     | NLD         | Noord-Holland |     731200 |
|  6 | ROT                     | NLD         | Zuid-Holland  |     593321 |
|  7 | HAA                     | NLD         | Zuid-Holland  |     440900 |
|  8 | UTR                     | NLD         | Utrecht       |     234323 |
|  9 | EIN                     | NLD         | Noord-Brabant |     201843 |
| 10 | TIL                     | NLD         | Noord-Brabant |     193238 |
+----+-------------------------+-------------+---------------+------------+
10 rows in set (0.01 sec)