MySQL常用命令学习(1)

MySQL常用命令学习(1)

前言

在上一章节中我们了解到MySQL的安装以及启动这一章我们学习简单的常用的命令。

输入查询

这些所有的操作都需要简历在数据库服务开启状态,并且打开客户端的情况下进行。

# 查询版本   查询时间
SELECT VERSION(), CURRENT_DATE;
# 按下回车输出如下:
+-----------+--------------+
| VERSION() | CURRENT_DATE |
+-----------+--------------+
| ********* | 2019-12-13   |
+-----------+--------------+
1 row in set (0.02 sec)

MySQL的一些说明:

  • 查询通常由一个SQL语句和一个分号组成。(某些情况不用,比如退出quit exit)

  • 当您发出查询时,mysql将其发送到服务器以执行并显示结果,然后打印另一个mysql>提示以指示它已准备好进行另一个查询。

  • mysql以表格形式(行和列)显示查询输出。第一行包含各列的标签。以下各行是查询结果。通常,列标签是您从数据库表中获取的列的名称。如果要获取表达式的值而不是表列(如上例所示),则 mysql使用表达式本身来标记该列。

  • mysql显示返回了多少行以及查询执行了多长时间,这使您对服务器性能有了一个大概的了解。这些值不精确,因为它们表示墙上时钟时间(而不是CPU或机器时间),并且受诸如服务器负载和网络延迟之类的因素影响。(为了简便起见,在“行中设定 ” 线有时不是在本章中剩余的实施例中所示)。

  • 可以在任何大写字母中输入关键字。以下查询是等效的:

SELECT VERSION(), CURRENT_DATE;
select version(), current_date;
SeLeCt vErSiOn(), current_DATE;

每一条查询语句后边必须添加";",因此可以一行写多个表达式,表达式以";"分隔。一个查询不必全都给出,因此需要几行的冗长查询不是问题。 mysql通过查找终止分号(而不是通过输入行的末尾)来确定语句的结尾。(换句话说,mysql 接受自由格式的输入:它收集输入行,但直到看到分号后才执行它们。)

mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+---------------+--------------+
| USER()        | CURRENT_DATE |
+---------------+--------------+
| root@localhost | 2019-12-13   |
+---------------+--------------+

如果您决定不想执行正在输入的查询,请输入以下命令来取消它 \c:

mysql> SELECT
    -> USER()
    -> \c
mysql>

提示和含义:

  • mysql>:准备进行新查询
  • ->:等待多行查询的下一行
  • '>:等待下一行,等待以单引号(')开头的字符串的完成
  • ">:等待下一行,等待以双引号(")开头的字符串的完成
  • >:等待下一行,等待以反引号()开头的标识符的完成
  • /*>:等待下一行,等待以开头的注释的完成 /*

创建和使用数据库

因为数据库语法很多都语义化,所以我就直接上命令了。

# 展示数据库
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+

# 使用test数据库为默认操作的数据库
mysql> USE test
Database changed

这里use可以不用加分号。

# 创建数据库
mysql> CREATE DATABASE menagerie;

在Unix下,数据库名称是区分大小写的(不像SQL关键字),所以你必须总是指到你的数据库 menagerie,而不是 Menagerie,MENAGERIE或一些其他变种。表名也是如此。(在Windows下,此限制不适用,尽管在整个给定查询中必须使用相同的字母大写来引用数据库和表。但是,由于多种原因,建议的最佳实践始终是使用与数据库已创建。)

mysql> USE menagerie
Database changed

创建表

mysql> SHOW TABLES;
Empty set (0.00 sec)

最困难的部分是确定数据库的结构应该是:每个表中需要什么表以及什么列。

使用一跳CREATE TABLE语句来创建一个指定表布局:

# 创建一个表  name owner... 每个属性后边的对应的是格式和长度
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
       species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

# 查看表
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                 |
+---------------------+

# 查看表是按预期方式创建的
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

将数据加载到表中

将文本文件加载到表中

如下数据放到pet.txt文件中,其中空格部分是单个制表符,用来区分不同的列,如果是NULL,就使用\N

Whistler  Gwen  bird  \N  1997-12-09  \N

将文本文件加载到pet表中,使用如下语句:

mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;

如果提示没有权限之类的诸如:

ERROR 1148 (42000): The used command is not allowed with this MySQL version

需要用点小操作改变一下权限:

  • 首先查看local-infile模块是否打开
show global variables like 'local_infile';

如果是value是OFF,那就需要将权限打开。

set global local_infile='ON';

然后查询发现已经启用了,退出MySQL,使用另一种方式打开:

mysql --local-infile=1 -u root -p

再次执行就能上传了。

还有一种方式添加数据

# 使用INSERT命令添加新记录
mysql> INSERT INTO pet
       VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

从表中检索信息

SELECT 语句提取信息

SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy;

what_to_select指示您要查看的内容。这可以是列的列表,也 *可以表示“ 所有列”。” which_table表示要从中检索数据的表。该WHERE 子句是可选的。如果存在,则 conditions_to_satisfy指定行必须满足的一个或多个条件才有资格进行检索。

选择所有数据

mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+

如果发现有数据错误,此时有两种方式解决:

  • 编辑pet.txt修改,然后清空表然后重载
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;
  • 另一种使用UPDATE语句
mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';

选择特定行

如果不需要看整个表格,只看部分表格,使用查看全部属实浪费精力眼神。所以选择特定行功能非常奥利给。

mysql> SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name   | owner | species | sex  | birth      | death      |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+

字符串比较通常不区分大小写,因此您可以将名称指定为'bowser', 'BOWSER'等等。查询结果相同。

您可以在任何列上指定条件,而不仅仅是 name。例如,

# 如果您想知道在1998年或之后出生的动物,请测试以下列 birth:
mysql> SELECT * FROM pet WHERE birth >= '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
+----------+-------+---------+------+------------+-------+

# 查找雌狗使用AND:
mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

# 也可以使用OR:
mysql> SELECT * FROM pet WHERE species = 'snake' OR species = 'bird';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL  |
| Slim     | Benny | snake   | m    | 1996-04-29 | NULL  |
+----------+-------+---------+------+------------+-------+

# 还可以混搭OR和AND:
mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
       OR (species = 'dog' AND sex = 'f');
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
# AND和 OR可以混合使用,尽管 AND优先级高于 OR。如果同时使用这两个运算符,则最好使用括号来明确指示应如何对条件进行分组:

选择特殊列

如果您不想看到表中的整个行,只需用逗号分隔您感兴趣的列即可。例如,如果您想知道动物何时出生,请选择name和 birth列:

mysql> SELECT name, birth FROM pet;
+----------+------------+
| name     | birth      |
+----------+------------+
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Buffy    | 1989-05-13 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+

也可以和上一节结合起来使用

mysql> SELECT name, species, birth FROM pet
       WHERE species = 'dog' OR species = 'cat';
+--------+---------+------------+
| name   | species | birth      |
+--------+---------+------------+
| Fluffy | cat     | 1993-02-04 |
| Claws  | cat     | 1994-03-17 |
| Buffy  | dog     | 1989-05-13 |
| Fang   | dog     | 1990-08-27 |
| Bowser | dog     | 1989-08-31 |
+--------+---------+------------+

给行排序

默认的排序顺序是升序,最小值先出现。要以倒序(降序)排序,请将DESC关键字添加到要排序 的列的名称上:

# 默认排序
mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name     | birth      |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+

# 指定排序
mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name     | birth      |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Claws    | 1994-03-17 |
| Fluffy   | 1993-02-04 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Buffy    | 1989-05-13 |
+----------+------------+

您可以对多个列进行排序,也可以按不同方向对不同的列进行排序。例如,要按升序对动物类型进行排序,然后按降序对动物类型内的出生日期进行排序(首先是最年轻的动物),请使用以下查询:

mysql> SELECT name, species, birth FROM pet
       ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+

日期计算

MySQL提供了一些函数,可用于对日期执行计算,例如,计算年龄或提取部分日期。

# 查询宠物的年龄
mysql> SELECT name, birth, CURDATE(),
       TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
       FROM pet;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
+----------+------------+------------+------+

# 再加个根据age排序
mysql> SELECT name, birth, CURDATE(),
       TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
       FROM pet ORDER BY age;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
+----------+------------+------------+------+

# 可以使用类似的查询来确定已经死亡的动物的死亡年龄。您可以通过检查death值 是否为来确定这些动物是哪些NULL。然后,对于那些没有NULL值的人,计算death和 birth值之间的差:
mysql> SELECT name, birth, death,
       TIMESTAMPDIFF(YEAR,birth,death) AS age
       FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+

# MySQL提供了几个用于提取日期的部分,如 YEAR(), MONTH()和 DAYOFMONTH()。

mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name     | birth      | MONTH(birth) |
+----------+------------+--------------+
| Fluffy   | 1993-02-04 |            2 |
| Claws    | 1994-03-17 |            3 |
| Buffy    | 1989-05-13 |            5 |
| Fang     | 1990-08-27 |            8 |
| Bowser   | 1989-08-31 |            8 |
| Chirpy   | 1998-09-11 |            9 |
| Whistler | 1997-12-09 |           12 |
| Slim     | 1996-04-29 |            4 |
| Puffball | 1999-03-30 |            3 |
+----------+------------+--------------+

NULL 值

从概念上讲,它NULL表示 “ 缺少的未知值 ”,并且与其他值的处理方式有所不同。

要测试NULL,请使用 IS NULL和IS NOT NULL运算符,如下所示:

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|         0 |             1 |
+-----------+---------------+
# 验证一下
mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
|         0 |             1 |          0 |              1 |
+-----------+---------------+------------+----------------+

模式匹配

MySQL提供了标准的SQL模式匹配以及基于扩展的正则表达式的模式匹配形式,该正则表达式类似于Unix实用程序所使用的 vi,grep和 sed。

SQL模式匹配使您可以_ 用来匹配任何单个字符并%匹配任意数量的字符(包括零个字符)。在MySQL中,默认情况下,SQL模式不区分大小写。这里显示一些示例。请勿使用 =或<>使用SQL模式时。改用LIKE或 NOT LIKE比较运算符。

# 查找以b开头的
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

# 查找以fy结尾的
mysql> SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+

# 查询包含w的
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+

# 要查找正好包含五个字符的名称
mysql> SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

MySQL提供的另一种模式匹配使用扩展的正则表达式。

# 要查找以开头的名称b
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b');
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

若要强制正则表达式比较区分大小写,请使用区分大小写的排序规则,或使用 BINARY关键字将字符串之一设置为二进制字符串,或指定c match-control字符。这些查询中的每个查询都只b在名称开头匹配小写字母:

# 区分大小写的开头b
SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b' COLLATE utf8mb4_0900_as_cs);
SELECT * FROM pet WHERE REGEXP_LIKE(name, BINARY '^b');
SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b', 'c');

# 要查找包含的名称w
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, 'w');
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+

# 要查找正好包含五个字符的名称
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^.....$');
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

# 您还可以使用 (“ repeat- -times ”)运算符编写上一个查询 : {n}n
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^.{5}$');
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

计数行

数据库通常用于回答以下问题:“ 表中某种类型的数据多久出现一次?” 例如,您可能想知道您拥有多少只宠物,或者每个所有者拥有多少只宠物,或者您可能想对动物进行各种普查操作。

# 查看表中有多少行
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
|        9 |
+----------+

如果查询每个所有者有多少宠物,可以使用:

mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Benny  |        2 |
| Diane  |        2 |
| Gwen   |        3 |
| Harold |        2 |
+--------+----------+

GROUP BY意思是根据什么的分组,也就是说想要查询以所有者为行统计不同所有者出现的次数。

# 每个物种和性别组合的动物数量:
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | NULL |        1 |
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+

# 使用时无需检索整个表 COUNT()。例如,仅对狗和猫执行的前一个查询如下所示:
mysql> SELECT species, sex, COUNT(*) FROM pet
       WHERE species = 'dog' OR species = 'cat'
       GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
+---------+------+----------+

# 或者,如果只想知道已知性别的动物,则按性别计算的动物数:
mysql> SELECT species, sex, COUNT(*) FROM pet
       WHERE sex IS NOT NULL
       GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+

# 如果ONLY_FULL_GROUP_BY启用了 SQL模式,则会发生错误:
mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
# 1 of SELECT list contains nonaggregated column 'menagerie.pet.owner';
# this is incompatible with sql_mode=only_full_group_by

# 如果ONLY_FULL_GROUP_BY未启用,则通过将所有行视为一个组来处理查询,但是为每个命名列选择的值是不确定的。服务器可以从任何行中自由选择值:
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT owner, COUNT(*) FROM pet;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Harold |        8 |
+--------+----------+
1 row in set (0.00 sec)

使用多个表

一个表经常是很局限性的,通常会使用很多个表,多个表之间的联系,就是这一节要了解的东西。

首先创建一个新表名叫event

mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
       type VARCHAR(15), remark VARCHAR(255));

其次导入数据

mysql> LOAD DATA LOCAL INFILE 'D:/mysql/event.txt' INTO TABLE event;

假如我们要查找宠物产仔的年龄,需要对比两个时间,一个是宠物生日在pet表,一个是宠物生仔的日期在event表上,具体操作:

mysql> SELECT pet.name,
       TIMESTAMPDIFF(YEAR,birth,date) AS age,
       remark
       FROM pet INNER JOIN event
         ON pet.name = event.name
       WHERE event.type = 'litter';
+--------+------+-----------------------------+
| name   | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy |    2 | 4 kittens, 3 female, 1 male |
| Buffy  |    4 | 5 puppies, 2 female, 3 male |
| Buffy  |    5 | 3 puppies, 3 female         |
+--------+------+-----------------------------+

关于这次查询需要注意几点:

  • FROM pet INNER JOIN event 链接两个表,因为查询需要从两个表取信息。

  • 当合并两个表的数据的时候,需要通过 ON 指定一下两个表的公共匹配部分,比如例子中的name,两个表都有,才能根据这两个相同的东西来匹配。查询使用INNER JOIN来合并表。如果一个名称在一个表里有,另一个表里没有,那就没有匹配到结果,就会说ON子句条件失败。

也可以不使用两个表来关联和并,也可以用同一个表做关联。比如给宠物配对,需要找同品种非同性别的搞。

mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
       FROM pet AS p1 INNER JOIN pet AS p2
         ON p1.species = p2.species
         AND p1.sex = 'f' AND p1.death IS NULL
         AND p2.sex = 'm' AND p2.death IS NULL;
+--------+------+-------+------+---------+
| name   | sex  | name  | sex  | species |
+--------+------+-------+------+---------+
| Fluffy | f    | Claws | m    | cat     |
| Buffy  | f    | Fang  | m    | dog     |
+--------+------+-------+------+---------+

ps. 今天总结的太多了,但是很简单,mysql的好多命令都很语义化,学起来并不难。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 什么是数据库? 数据库是存储数据的集合的单独的应用程序。每个数据库具有一个或多个不同的API,用于创建,访问,管理...
    chen_000阅读 4,028评论 0 19
  • MySQL技术内幕:SQL编程 姜承尧 第1章 SQL编程 >> B是由MySQL创始人之一Monty分支的一个版...
    沉默剑士阅读 2,402评论 0 3
  • 1. 了解SQL 1.1 数据库基础 ​ 学习到目前这个阶段,我们就需要以某种方式与数据库打交道。在深入学习MyS...
    锋享前端阅读 1,037评论 0 1
  • --- layout: post title: "如果有人问你关系型数据库的原理,叫他看这篇文章(转)" date...
    蓝坠星阅读 775评论 0 3
  • 1 iOS跳转界面时隐藏tabBar的方法 2 Iphone隐藏和显示TabBar的方法1.隐藏TabBar: 2...
    騂跃神话阅读 16,484评论 0 22