MySQL使用教程(三)

本文介绍了SQL查询的基本语法和高级技巧,包括从表中检索信息、选择特定行和列、使用模式匹配、处理NULL值、进行计数操作以及联合多个表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.3.4. 从表索信息

3.3.4.1. 选择有数据

3.3.4.2. 选择特殊行

3.3.4.3. 选择特殊列

3.3.4.4.

3.3.4.5. 日期

3.3.4.6. NULL操作

3.3.4.7. 模式匹配

3.3.4.8. 数行

3.3.4.9. 使用1个以上的表
 

SELECT句用来从数据表中索信息。句的一般格式是:

SELECT what_to_select

FROM which_table

WHERE conditions_to_satisfy;

what_to_select指出你想要看到的内容,可以是列的一个表,或*表示所有的列which_table指出你想要从其索数据的表。WHERE子句是可选项,如果选择该项conditions_to_satisfy指定行必须满足的索条件。

3.3.4.1. 选择所有数据

SELECT简单的形式是从一个表中索所有记录

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       |

+----------+--------+---------+------+------------+------------+

如果你想要浏览整个表,可以使用这种形式的SELECT例如,刚刚了初始数据集以后。也有可能你想到Bowser的生日看起来不很查阅你原来的家,你发现正确的出生年是1989,而不是1979

至少有两修正方法:

·         编辑文件“pet.txt”改正错误,然后使用DELETELOAD DATA清空并重新装:

·               mysql> DELETE FROM pet;

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

然而, 如果这样操做,必重新Puffball记录

·         用一个UPDATE修正错误记录

·               mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';

UPDATE只更改有问题记录,不需要重新装数据表。

3.3.4.2. 选择特殊行

如上所示,索整个表是容易的。只需要从SELECT句中WHERE子句。但是一般你不想看到整个表,特地当表得很大。相反,你通常回答一个具体的问题更感趣,在这种情况下在你想要的信息上行一些限制。看一些回答的有物的问题选择查询

可以从表中只选择特定的行。例如,如果你想要验证Bowser的生日所做的更改,按下述方法选择Bowser记录

mysql> SELECT * FROM pet WHERE name ='Bowser';

+--------+-------+---------+------+------------+------------+

| name   | owner | species |sex  | birth      |death      |

+--------+-------+---------+------+------------+------------+

| Bowser | Diane |dog     | m    | 1989-08-31 | 1995-07-29 |

+--------+-------+---------+------+------------+------------+

证实正确的年份记录为1989,而不是1979

字符串比较时通常大小些不敏感,因此你可以将名字指定"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  |

+----------+-------+---------+------+------------+-------+

可以合条件,例如,找出雌性的狗:

mysql> SELECT * FROM pet WHERE species= 'dog' AND sex = 'f';

+-------+--------+---------+------+------------+-------+

| name  | owner  | species |sex  | birth      | death |

+-------+--------+---------+------+------------+-------+

| Buffy | Harold |dog     | f    | 1989-05-13 | NULL  |

+-------+--------+---------+------+------------+-------+

上面的查询使用AND逻辑操作符,也有一个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  |

+----------+-------+---------+------+------------+-------+

ANDOR可以混用,但ANDOR具有更高的。如果你使用两个操作符,使用括号指明如何条件行分是一个好主意:

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  |

+-------+--------+---------+------+------------+-------+

3.3.4.3. 选择特殊列

如果你不想看到表中的所有行,就命名你感趣的列,用逗号分。例如,如果你想要知道你的物什么时候出生的,选择namebirth列:

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 owner FROM pet;

+--------+

| owner  |

+--------+

| Harold |

| Gwen   |

| Harold |

| Benny  |

| Diane  |

| Gwen   |

| Gwen   |

| Benny  |

| Diane  |

+--------+

注意该查询只是简单记录owner列,并且他中的一些出多次。了使出减到最少,增加关键DISTINCT索出个唯一的记录

mysql> SELECT DISTINCT owner FROM pet;

+--------+

| owner  |

+--------+

| Benny  |

| Diane  |

| Gwen   |

| Harold |

+--------+

可以使用一个WHERE子句合行选择与列选择。例如,要想查询狗和猫的出生日期,使用查询

mysql> SELECT name, species, birth FROMpet

    -> 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 |

+--------+---------+------------+

3.3.4.4. 

你可能已注意到前面的例子中果行没有以特定的示。然而,当行按某方式排序检查查询输出通常更容易。了排序果,使用ORDER BY子句。

里是物生日,按日期排序:

mysql> SELECT name, birth FROM petORDER 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 |

+----------+------------+

在字符型列上,与所有其他比操作似,功能正常情况下是以区分大小写的方式行的。意味着,于等同但大小写不同的列,并未定序。于某一列,可以使用BINARY行区分大小写的分功能,如:ORDER BYBINARY col_name.

排序是升序,最小的在第一。要想以降序排序,在你正在排序的列名上增加DESC(降序关键字:

mysql> SELECT name, birth FROM petORDER 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 FROMpet

    -> 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 |

+----------+---------+------------+

注意DESC关键适用于在它前面的列名(birth);不影响species列的排序序。

3.3.4.5. 日期

MySQL提供了几个函数,可以用来算日期,例如,算年或提取日期部分。

要想确定物有多大,可以算当前日期的年和出生日期之的差。如果当前日期的日年比出生日期早,减去一年。以下查询显示了物的出生日期、当前日期和年的年数字。

mysql> SELECT name, birth, CURDATE(),

    -> (YEAR(CURDATE())-YEAR(birth))

    -> -(RIGHT(CURDATE(),5)<RIGHT(birth,5))

    -> 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 |

+----------+------------+------------+------+

YEAR()提取日期的年部分,RIGHT()提取日期的MM-DD ()部分的最右面5个字符。比MM-DD的表达式部分的一般10,如果CURDATE()的年比birth的年早,年份减去1。整个表达式有些懂,使用alias(age)来使出的列标记更有意

尽管查询可行,如果以某个序排列行,能更容易地浏览结果。添加ORDER BYname子句按照名字对输行排序够实现

mysql> SELECT name, birth, CURDATE(),

    -> (YEAR(CURDATE())-YEAR(birth))

    -> -(RIGHT(CURDATE(),5)<RIGHT(birth,5))

    -> AS age

    -> FROM pet ORDER BYname;

+----------+------------+------------+------+

| name     |birth      | CURDATE()  | age  |

+----------+------------+------------+------+

| Bowser   | 1989-08-31 |2003-08-19 |   13 |

| Buffy    | 1989-05-13 |2003-08-19 |   14 |

| Chirpy   | 1998-09-11 |2003-08-19 |    4 |

| Claws    | 1994-03-17 |2003-08-19 |    9 |

| Fang     | 1990-08-27 |2003-08-19 |   12 |

| Fluffy   | 1993-02-04 |2003-08-19 |   10 |

| Puffball | 1999-03-30 | 2003-08-19|    4 |

| Slim     | 1996-04-29 |2003-08-19 |    7 |

| Whistler | 1997-12-09 | 2003-08-19|    5 |

+----------+------------+------------+------+

了按age而非name排序出,只要再使用一个ORDER BY子句:

mysql> SELECT name, birth, CURDATE(),

    -> (YEAR(CURDATE())-YEAR(birth))

    -> -(RIGHT(CURDATE(),5)<RIGHT(birth,5))

    -> AS age

    -> FROM pet ORDER BYage;

+----------+------------+------------+------+

| 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物,需要算出deathbirth的差:

mysql> SELECT name, birth, death,

    -> (YEAR(death)-YEAR(birth))- (RIGHT(death,5)<RIGHT(birth,5))

    -> AS age

    -> FROM pet WHEREdeath IS NOT NULL ORDER BY age;

+--------+------------+------------+------+

| name   |birth      | death      |age  |

+--------+------------+------------+------+

| Bowser | 1989-08-31 | 1995-07-29|    5 |

+--------+------------+------------+------+

查询使用death ISNOT NULL而非death !=NULL,因NULL是特殊的,不能使用普通比符来比,以后会出解。参3.3.4.6“NULL操作

如果你想要知道哪个物下个月生日,怎么办这类计算,年和天是无的,你只需要提取birth列的月份部分。MySQL提供几个日期部分的提取函数,例如YEAR( )MONTH( )DAYOFMONTH()。在MONTH()是适合的函数。了看它怎工作,运行一个简单查询birthMONTH(birth)

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 |

+----------+------------+--------------+

找出下个月生日的物也是容易的。假定当前月是4月,那4你可以找在5月出生的 (5),方法是:

mysql> SELECT name, birth FROM petWHERE MONTH(birth) = 5;

+-------+------------+

| name  |birth      |

+-------+------------+

| Buffy | 1989-05-13 |

+-------+------------+

如果当前月份是12月,就有点复杂了。你不能只把1加到月份数(12)上并找在13月出生的物,因没有这样的月份。相反,你应寻找在1月出生的(1) 

你甚至可以查询,不管当前月份是什它都能工作。采用这种方法不必在查询中使用一个特定的月份,DATE_ADD( )在一个定的日期上加上时间间隔。如果在NOW( )上加上一个月,然后用MONTH()提取月份,生生日所在月份:

mysql> SELECT name, birth FROM pet

    -> WHEREMONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));

完成的另一个方法是加1以得出当前月份的下一个月(在使用取模函数(MOD)后,如果月份当前120)

mysql> SELECT name, birth FROM pet

    -> WHEREMONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;

注意,MONTH返回在112的一个数字,且MOD(something,12)返回在011的一个数字,因此必MOD( )以后加1,否将从11( 11 )跳到1(1)

3.3.4.6. NULL操作

NULL可能令人感到奇怪直到你习惯它。概念上,NULL意味着没有未知,且它被看作与众不同的测试NULL,你不能使用算操作符例如=<!=明它,试试下列查询

mysql> SELECT 1 = NULL, 1 <>NULL, 1 < NULL, 1 > NULL;

+----------+-----------+----------+----------+

| 1 = NULL | 1 <> NULL | 1 < NULL |1 > NULL |

+----------+-----------+----------+----------+

|     NULL|      NULL |     NULL|     NULL |

+----------+-----------+----------+----------+

然你不能通过这些比得到有意果。相反使用IS NULLIS NOTNULL操作符:

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;

+-----------+---------------+

| 1 IS NULL | 1 IS NOT NULL |

+-----------+---------------+

|        0 |             1 |

+-----------+---------------+

注意在MySQL中,0 NULL意味着假而其它意味着真。布运算的默1

NULL的特殊理即是在前面的章中,了决定哪个物不再是活着的,使用death ISNOT NULL而不使用death !=NULL的原因。

GROUP BY中,两个NULL值视为相同。

ORDER BY,如果运行 ORDER BY... ASCNULL在最前面,若运行ORDER BY... DESCNULL在最后面。

NULL操作的常见错误是不能在定义为NOT NULL的列内插入0或空字符串,但事并非如此。在NULL表示"没有数"的地方有数。使用IS [NOT] NULL可以很容易地测试,如下所示:

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 |

+-----------+---------------+------------+----------------+

因此完全可以在定义为NOT NULL的列内插入0或空字符串,实际NOT NULL。参A.5.3NULL问题

3.3.4.7. 模式匹配

MySQL提供准的SQL模式匹配,以及一基于象Unix用程序如vigrepsed展正表达式模式匹配的格式。

SQL模式匹配允你使用“_”匹配任何个字符,而“%”匹配任意数目字符(包括零字符)。在 MySQL中,SQL的模式默是忽略大小写的。下面出一些例子。注意使用SQL模式,不能使用=!=;而使用LIKENOT LIKE操作符。

要想找出以“b”开头的名字:

mysql> SELECT * FROM pet WHERE nameLIKE '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 nameLIKE '%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 nameLIKE '%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       |

+----------+-------+---------+------+------------+------------+

要想找出正好包含5个字符的名字,使用“_”模式字符:

mysql> SELECT * FROM pet WHERE nameLIKE '_____';

+-------+--------+---------+------+------------+-------+

| name  | owner  | species |sex  | birth      | death |

+-------+--------+---------+------+------------+-------+

| Claws | Gwen   |cat     | m    | 1994-03-17 | NULL  |

| Buffy | Harold |dog     | f    | 1989-05-13 | NULL  |

+-------+--------+---------+------+------------+-------+

MySQL提供的模式匹配的其它型是使用展正表达式。当你对这类模式行匹配测试时,使用REGEXPNOT REGEXP操作符(RLIKENOT RLIKE,它是同义词)

展正表达式的一些字符是:

·         ‘.匹配任何个的字符。

·         字符“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”“b”“c”了命名字符的范,使用一个“-“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。

·         “ * ”匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的“x”字符,“[0-9]*”匹配任何数量的数字,而“.*”匹配任何数量的任何字符。

·        如果REGEXP模式与被测试值的任何地方匹配,模式就匹配(不同于LIKE模式匹配,只有与整个匹配,模式才匹配)

·        了定位一个模式以便它必匹配被测试值始或尾,在模式使用“^”在模式的尾用“$”

展正表达式如何工作,下面使用REGEXP重写上面所示的LIKE查询

了找出以“b”开头的名字,使用“^”匹配名字的始:

mysql> SELECT * FROM pet WHERE nameREGEXP '^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 |

+--------+--------+---------+------+------------+------------+

如果你想制使REGEXP区分大小写,使用BINARY关键字使其中一个字符串变为制字符串。该查询只匹配名称首字母的小写‘b

mysql> SELECT * FROM pet WHERE nameREGEXP BINARY '^b';

了找出以“fy”尾的名字,使用“$”匹配名字的尾:

mysql> SELECT * FROM pet WHERE nameREGEXP '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 nameREGEXP '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       |

+----------+-------+---------+------+------------+------------+

既然如果一个正表达式出的任何地方,其模式匹配了,就不必在先前的查询中在模式的两放置一个通配符以使得它匹配整个,就像你使用了一个SQL模式那

了找出包含正好5个字符的名字,使用“^”“$”匹配名字的始和尾,和5“.”例在两者之

mysql> SELECT * FROM pet WHERE nameREGEXP '^.....$';

+-------+--------+---------+------+------------+-------+

| name  | owner  | species |sex  | birth      | death |

+-------+--------+---------+------+------------+-------+

| Claws | Gwen   |cat     | m    | 1994-03-17 | NULL  |

| Buffy | Harold |dog     | f    | 1989-05-13 | NULL  |

+-------+--------+---------+------+------------+-------+

你也可以使用“{n}”n操作符重写前面的查询

mysql> SELECT * FROM pet WHERE nameREGEXP '^.{5}$';

+-------+--------+---------+------+------------+-------+

| name  | owner  | species |sex  | birth      | death |

+-------+--------+---------+------+------------+-------+

| Claws | Gwen   |cat     | m    | 1994-03-17 | NULL  |

| Buffy | Harold |dog     | f    | 1989-05-13 | NULL  |

+-------+--------+---------+------+------------+-------+

GMySQL表达式 提供了于正表达式的句法的详细信息。

3.3.4.8. 数行

数据库经常用于回答问题某个的数据在表中出?例如,你可能想要知道你有多少物,或位主人有多少物,或你可能想要你的行各种类型的普

算你物的数目与pet表中有多少行?是同问题,因为每物有一个记录COUNT(*)函数算行数,所以物数目的查询应为

mysql> SELECT COUNT(*) FROM pet;

+----------+

| COUNT(*) |

+----------+

|        9|

+----------+

在前面,你索了物的人的名字。如果你想要知道个主人有多少物,你可以使用COUNT( )函数:

mysql> SELECT owner, COUNT(*) FROM petGROUP BY owner;

+--------+----------+

| owner  | COUNT(*) |

+--------+----------+

| Benny |        2 |

| Diane |        2 |

| Gwen  |        3 |

| Harold|        2 |

+--------+----------+

注意,使用GROUP BY对每owner的所有记录,没有它,你会得到错误消息:

mysql> SELECT owner, COUNT(*) FROM pet;

ERROR 1140 (42000): Mixing of GROUP columns(MIN(),MAX(),COUNT(),...)

with no GROUP columns is illegal if there isno GROUP BY clause

COUNT( )GROUP BY以各方式分你的数据。下列例示出物普操作的不同方式。

每种动物的数量:

mysql> SELECT species, COUNT(*) FROMpet GROUP BY species;

+---------+----------+

| species | COUNT(*) |

+---------+----------+

| bird   |        2 |

| cat    |        2 |

| dog    |        3 |

| hamster|        1 |

| snake  |        1 |

+---------+----------+

每种物数量:

mysql> SELECT sex, COUNT(*) FROM pet GROUPBY sex;

+------+----------+

| sex  | COUNT(*) |

+------+----------+

| NULL|        1 |

| f   |        4 |

| m   |        4 |

+------+----------+

(在出中,NULL表示未知性。)

种类和性别组合的物数量:

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 NOTNULL

    -> 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 |

+---------+------+----------+

3.3.4.9. 使用1个以上的表
 

pet表追踪你有哪个物。如果你想要记录其它相信息,例如在他一生中看医或何后代出生,你需要另外的表。这张应该像什呢?需要:

·         它需要包含物名字以便你知道个事件属于哪个物。

·         需要一个日期以便你知道事件是什么时生的。

·         需要一个描述事件的字段。

·         如果你想要事件行分需要一个事件型字段。

合上述因素,event表的CREATETABLE应为

mysql> CREATE TABLE event (nameVARCHAR(20), date DATE,

    -> type VARCHAR(15),remark VARCHAR(255));

pet表,最容易的方法是建包含信息的用定位符分隔的文本文件来装初始记录

name

date

type

remark

Fluffy

1995-05-15

litter

4 kittens, 3 female, 1 male

Buffy

1993-06-23

litter

5 puppies, 2 female, 3 male

Buffy

1994-06-19

litter

3 puppies, 3 female

Chirpy

1999-03-21

vet

needed beak straightened

Slim

1997-08-03

vet

broken rib

Bowser

1991-10-12

kennel

 

Fang

1991-10-12

kennel

 

Fang

1998-08-28

birthday

Gave him a new chew toy

Claws

1998-03-17

birthday

Gave him a new flea collar

Whistler

1998-12-09

birthday

First birthday

采用如下方式装载记录

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

根据你从已运行在pet表上的查询中学到的,你应该event表中记录索;原理是一的。但是什么时event表本身不能回答你可能问题呢?

当他有了一,假定你想要找出物的年。我前面看到了如何通两个日期算年event表中有母的生日期,但是算母的年,你需要她的出生日期,存pet表中。查询需要两个表:

mysql> SELECT pet.name,

    -> (YEAR(date)-YEAR(birth))- (RIGHT(date,5)<RIGHT(birth,5)) AS age,

    -> remark

    -> FROM pet, event

    -> WHERE pet.name =event.name AND event.type = 'litter';

+--------+------+-----------------------------+

| name   | age  |remark                     |

+--------+------+-----------------------------+

| Fluffy |    2 | 4 kittens, 3female, 1 male |

| Buffy  |    4 | 5puppies, 2 female, 3 male |

| Buffy  |    5 | 3puppies, 3 female         |

+--------+------+-----------------------------+

该查询要注意的几件事情:

·        FROM子句列出两个表,因为查询需要从两个表提取信息。

·        当从多个表(联结)信息,你需要指定一个表中的记录能匹配其它表的记录简单,因都有一个name列。查询使用WHERE子句基于name来匹配2个表中的记录

·        name列出在两个表中,当引用列,你一定要指定哪个表。把表名附在列名前即可以实现

你不必有2个不同的表来联结。如果你想要将一个表的记录与同一个表的其它记录进行比,可以将一个表联结到自身。例如,了在你的物之中繁殖配偶,你可以用pet联结自身来行相似种类的雄雌配

 

mysql> SELECT p1.name, p1.sex, p2.name,p2.sex, p1.species

    -> FROM pet AS p1,pet AS p2

    -> WHERE p1.species= p2.species AND p1.sex = 'f' AND p2.sex = 'm';

+--------+------+--------+------+---------+

| name   | sex  |name   | sex  | species |

+--------+------+--------+------+---------+

| Fluffy | f    | Claws | m    | cat     |

| Buffy  | f    |Fang   | m    | dog     |

| Buffy  | f    | Bowser| m    | dog     |

+--------+------+--------+------+---------+

查询中,我们为表名指定名以便能引用列并且使得一个列引用与哪个表例相关联更直

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值