中国网管论坛's Archiver

木木 发表于 2004-4-16 02:25

常用的 mysql Z法例

8.1 B接c嚅_服照
榱诉B接服掌鳎你{用mysqlr,你通常⑿枰提供一MySQL用裘和很可能,一口令。如果服掌鬟\行在不是你登的一_C器上,你也⑿枰指定主C名。M你的管理T以找出你使用什NB接颠M行B接(即,那主C,用裘字和使用的口令)。一旦你知道正_的担你能像@舆B接:

shell> mysql -h host -u user -p
Enter password: ********

********代表你的口令;mysql@示Enter password:提示r入它。

如果能工作,你看mysql>提示後的一些介B信息:

shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 459 to server version: 3.22.20a-log

Type 'help' for help.

mysql>

提示符告V你mysql槟爿入命令。

一些MySQL安b允S用粢浴anoymous”(匿名)用暨B接在本地主C上\行的服掌鳌H绻在你的C器是@N情r,你能通^]有任何x地{用mysqlc服掌鬟B接:

shell> mysql

在你成功地B接後,你可以在mysql>提示下打入QUITSr嚅_:
mysql> QUIT
Bye

你也可以I入control-D嚅_。

在下列章的大多道子都假O你B接到服掌鳌Smysql>提示指明他。

8.2 入查
_保你B接上了服掌鳎如在先前的章的。@幼霰旧⒉贿x袢魏砉ぷ鳎但是那很好。倪@cv,知道P於如何出的一c知R,比R上跳至建表、o他bdK且乃z索要淼闹匾。本描述入命令的基本原t,使用查,你能L自己mysql是如何工作的。

@是一蔚拿令,要求服掌鞲嬖V你它的版本和前日期。在mysql>提示打入如下命令K按回I:

mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| version()    | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19  |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>

@f明P於mysql准事:

一命令通常由SQLZ句M成,S後有一分。(有一些例外不需要一分。早先提到的QUIT是他之一。我⒁葬峥吹狡渌。)
你l出一命令r,mysqll送它o服掌K@示Y果,然後打出另外一mysql>@示它浜媒邮芰硗獾拿令。
mysql以一表格(行和列)@示查出。第一行包含列的撕,S後的行是Y果。通常, 列撕是你取自毂淼牧械拿字。如果你正在z索一表_式而非表列的值(如u的例子),mysql用表_式本身擞列。
mysql@示多少行被返回,和查花了多L绦校它o你提供服掌餍阅艿囊大致概念。因樗表示rrg(不是 CPU 或C器rg),K且因樗受到T如服掌髫d和Wj延r的影,因此@些值是不精_的。(榱撕,在本章剩下的例子中不再@示“集合中的行”。)
PI~可以以任何大小字符被入。下列是等r的:

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

@e有另外一查,它f明你能mysql用作一蔚挠算器:
mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+-------------+---------+
|    0.707107 |      25 |
+-------------+---------+

至今@示的命令是相短的,涡姓Z句。你甚至能在涡猩陷入多lZ句,b是以一分Y束每一l:

mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| version()    |
+--------------+
| 3.22.20a-log |
+--------------+

+---------------------+
| NOW()              |
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+

一命令不必全在一为行o出,所以需要多行的^L命令不是一}。mysql通^ふ医K止的分而不是ふ逸入行的Y束Q定你的Z句在哪航Y束。(Q句f,mysql接受自由格式入:它收集入行但绦兴直到它看分。)

@e是一蔚亩嘈姓Z句的例子:

mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+--------------------+--------------+
| USER()            | CURRENT_DATE |
+--------------------+--------------+
| joesmith@localhost | 1999-03-18  |
+--------------------+--------------+
在@例子中,在你入一多行查的第一行後,要注意提示符如何mysql>->,@正是mysql如何指出它]到完整的Z句K且正在等待剩N的部分。提示符是你的朋友,因樗提供有r值的反,如果你使用反,你⒖是知道mysql正在等待什N。

如果你Q定,你不想要绦心阍谳入^程中入的一命令,打入\c取消它:

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

@e也要注意提示符,在你打入\c以後,它切Q回到mysql>,提供反以表明mysql浣邮芤新命令。

下表@示出你可以看的各提示符KY他意味著mysql在什NB下:

提示符 意思  
mysql>  浜媒邮苄旅令
->  等待多行命令的下一行
'>  等待下一行,收集以我(“'”)_始的字符串  
">  等待下一行,收集以p引(“"”)_始的字符串

你打算在一涡猩习l出一命令r,多行Z句通常“偶然”出F,但是忘K止的分。在@N情r中,mysql等待M一步入:

mysql> SELECT USER()
    ->

如果@l生在你身上(你J槟爿完了Z句但是唯一的反是一->提示符),很可能mysql正在等待分。如果你]有注意到提示符正在告V你什N,在JR到你需要做什N之前,你可能花一rgy坐在那骸_M入一分完成Z句,K且mysql绦兴:

mysql> SELECT USER()
    -> ;
+--------------------+
| USER()            |
+--------------------+
| joesmith@localhost |
+--------------------+

'>和">提示符出F在在字符串收集期g。在MySQL中,你可以由“'”或“"”字符括起淼淖址串 (例如,'hello'或"goodbye"),K且mysql你M入跨越多行的字符串。你看到一'>或">提示符r,@意味著你已入了包含以“'”或“"”括字符_始的字符串的一行,但是]有入K止字符串的匹配引。如果你_正在入一多行字符串,很好,但是果真如此幔坎槐M然。更常的,'>和">提示符@示你粗心地省掉了一引字符。例如:

mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
    ">

如果你入SELECTZ句,然後按回IK等待Y果,什N都]有出F。不要@,“槭颤N查@NL呢?”,注意">提示符提供的索。它告V你mysql期望到一未K止字符串的N下部分。(你在Z句中看e`幔孔址串"Smith正好G失第二引。)
走到@一步,你做什N?最蔚氖侨∠命令。然而,在@N情r下,你不能b是打入\c,因mysql作樗正在收集的字符串的一部分斫忉它!相反,入P]的引字符(@mysql知道你完成了字符串),然後打入\c:

mysql> SELECT * FROM my_table WHERE name = "Smith AND age < 30;
    "> "\c
mysql>

提示符回到mysql>,@示mysql浜媒邮芤新命令了。

知道'>和">提示符意味著什N是很重要的,因槿绻你e`地入一未K止的字符串,任何比你下一步入的行好像⒁被mysql忽略--包括包含QUIT的行!@可能相含糊,特e是在你能取消前命令前,如果你不知道你需要提出K止引。

8.3 常用查的例子
下面是一些W如何用MySQL解Q一些常}的例子。

一些例子使用毂怼shop”,包含某商人的每篇文章(物品)的r格。假定每商人的每篇文章有一为的固定r格,那N(物品,商人)是的主I。

你能@建例子毂恚

CREATE TABLE shop (
article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
dealer  CHAR(20)                DEFAULT ''    NOT NULL,
price  DOUBLE(16,2)            DEFAULT '0.00' NOT NULL,
PRIMARY KEY(article, dealer));

INSERT INTO shop VALUES
(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),
(3,'D',1.25),(4,'D',19.95);

好了,例子是@拥模

SELECT * FROM shop

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | A      |  3.45 |
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | B      |  1.45 |
|    0003 | C      |  1.69 |
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

8.3.1 列的最大值
“最大的物品是什N?”

SELECT MAX(article) AS article FROM shop

+---------+
| article |
+---------+
|      4 |
+---------+

8.3.2 碛心列的最大值的行
“找出最F的文章的、商人和r格”

在ANSI-SQL中@很容易用一子查做到:

SELECT article, dealer, price
FROM  shop
WHERE  price=(SELECT MAX(price) FROM shop)

在MySQL中(]有子查)就用2步做到:

用一SELECTZ句谋碇械玫阶畲笾怠
使用值出H的查:
SELECT article, dealer, price
FROM  shop
WHERE  price=19.95

另一解Q方案是按r格降序排序所有行K用MySQL特定LIMIT子句b得到的第一行:

SELECT article, dealer, price
FROM  shop
ORDER BY price DESC
LIMIT 1

注意:如果有多最F的文章( 例如每19.95),LIMIT解Q方案HH@示他之一!

8.3.3 列的最大值:按M:b有值
“每篇文章的最高的r格是什N?”

SELECT article, MAX(price) AS price
FROM  shop
GROUP BY article

+---------+-------+
| article | price |
+---------+-------+
|    0001 |  3.99 |
|    0002 | 10.99 |
|    0003 |  1.69 |
|    0004 | 19.95 |
+---------+-------+

8.3.4 碛心字段的Mg最大值的行
“γ科文章,找出有最F的r格的交易者。”

在ANSI SQL中,我可以用@右子查做到:

SELECT article, dealer, price
FROM  shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article)

在MySQL中,最好是分撞阶龅剑

得到一表(文章,maxprice)。8.3.4 碛心域的Mg最大值的行。
γ科文章,得到於存ψ畲r格的行。
@可以很容易用一Rr表做到:

CREATE TEMPORARY TABLE tmp (
        article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
        price  DOUBLE(16,2)            DEFAULT '0.00' NOT NULL);

LOCK TABLES article read;

INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;

SELECT article, dealer, price FROM shop, tmp
WHERE shop.article=tmp.articel AND shop.price=tmp.price;

UNLOCK TABLES;

DROP TABLE tmp;

如果你不使用一TEMPORARY表,你也必i定“tmp”表。

“它能一查做到幔俊

是的,但是b有使用我Q之椤MAX-CONCAT”的一相低效的:

SELECT article,
      SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer,
  0.00+LEFT(      MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price
FROM  shop
GROUP BY article;

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | C      |  1.69 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

最後例子然能通^在客舫绦蛑蟹指钸BY的列使它更有效一c。

8.3.5 使用外I
不需要外IY2表。

MySQL唯一不做的事情是CHECK以保C你使用的I_在你正在引用表中存在,K且它不自挠幸外I定x的表中h除行。如果你像平常那邮褂媚愕逆I值,它⒐ぷ鞯煤芎茫

CREATE TABLE persons (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name CHAR(60) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE shirts (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
    color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
    owner SMALLINT UNSIGNED NOT NULL REFERENCES persons,
    PRIMARY KEY (id)
);

INSERT INTO persons VALUES (NULL, 'Antonio Paz');

INSERT INTO shirts VALUES
(NULL, 'polo', 'blue', LAST_INSERT_ID()),
(NULL, 'dress', 'white', LAST_INSERT_ID()),
(NULL, 't-shirt', 'blue', LAST_INSERT_ID());

INSERT INTO persons VALUES (NULL, 'Lilliana Angelovska');

INSERT INTO shirts VALUES
(NULL, 'dress', 'orange', LAST_INSERT_ID()),
(NULL, 'polo', 'red', LAST_INSERT_ID()),
(NULL, 'dress', 'blue', LAST_INSERT_ID()),
(NULL, 't-shirt', 'white', LAST_INSERT_ID());

SELECT * FROM persons;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | Antonio Paz        |
|  2 | Lilliana Angelovska |
+----+---------------------+

SELECT * FROM shirts;
+----+---------+--------+-------+
| id | style  | color  | owner |
+----+---------+--------+-------+
|  1 | polo    | blue  |    1 |
|  2 | dress  | white  |    1 |
|  3 | t-shirt | blue  |    1 |
|  4 | dress  | orange |    2 |
|  5 | polo    | red    |    2 |
|  6 | dress  | blue  |    2 |
|  7 | t-shirt | white  |    2 |
+----+---------+--------+-------+

SELECT s.* FROM persons p, shirts s
WHERE p.name LIKE 'Lilliana%'
  AND s.owner = p.id
  AND s.color &lt;&gt; 'white';

+----+-------+--------+-------+
| id | style | color  | owner |
+----+-------+--------+-------+
|  4 | dress | orange |    2 |
|  5 | polo  | red    |    2 |
|  6 | dress | blue  |    2 |
+----+-------+--------+-------+

木木 发表于 2004-4-16 02:25

8.4 造K使用一
既然你知道怎虞入命令,F在是存取一斓r候了。

假定在你的家(你的“游@”)中有很多物,K且你想追P於他各N各宇型的信息。你可以通^建表肀4婺愕K根所需要的信息bd他做到,然後你可以通^谋碇z索砘卮痍P於你的游锊煌N的}。本@示如何做到所有@些事情:

怎建一
怎建一毂
怎友bd到毂
怎右愿鞣N方法谋碇z索
怎邮褂枚表
游@是蔚(故意的),但是不y把它想像成可能用到相似型斓恼世界情r。例如,@拥囊炷鼙灰r夫用碜粉家畜,或由一Ft追病畜。

使用SHOWZ句找出在服掌魃袭前存在什N欤

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test    |
| tmp      |
+----------+

炝斜砜赡茉谀愕C器上是不同的,但是mysql和test旌芸赡艿脑谄溟g。mysql是必需的,因樗描述用舸嫒嘞蓿test旖常作橐工作^提供o用粼身手。

如果test齑嬖冢L存取它:

mysql> USE test
Database changed

注意,USE,似QUIT,不需要一分。(如果你喜g,你可以用一分K止@拥恼Z句;@oK)USEZ句在使用上也有另外一特殊的地方:它必在一涡猩辖o出。

你可列在後面的例子中使用test(如果你能L它),但是你在建的任何|西可以被cL它的其他人h除,榱诉@原因,你可能你的MySQL管理TS可你自己使用的一臁<俣你想要{用你的menagerie,管理T需要绦幸@拥拿令:

mysql> GRANT ALL ON menagerie.* TO your_mysql_name;

@eyour_mysql_name是分配o你的MySQL用裘。

8.4.1 建Kx用一
如果在O置你的嘞r,管理T槟建了欤你可以_始使用它。否t,你需要自己建它:

mysql> CREATE DATABASE menagerie;

在Unix下,烀字是^分大小的(不像SQLPI~),因此你必是以menagerie引用你的欤不是Menagerie、MENAGERIE或一些其他N。Ρ砻也是@拥摹#ㄔWindows下,限制不m用,M管你必在一o定的查中使用同拥拇笮硪用旌捅怼#

建了一K不x定以使用它,你必明_地做@件事。榱耸menagerieQ楫前的欤使用@命令:

mysql> USE menagerie
Database changed

你的祀b需要建一次,但是你必在每次右mysqlr槭褂枚x袼。你可以由l出上面一USEZ句做到。另外,你{用rmysql,你可在命令行上x欤就在你可能需要提供的任何B接抵後指定其名字。例如:

shell> mysql -h host -u user -p menagerie
Enter password: ********

注意,menagerie不是你在u所示命令的口令。如果你想要在命令行上在-px後提供你的口令,你必做到]有多N的空格(例如,如-pmypassword,不是-p mypassword)。然而,不建h把你的口令放在命令行上,因檫@幼霭阉暴露出恚能被在你的C器上登的其他用舾Q探到。

8.4.2 建一毂
建焓侨菀椎牟糠郑但是在@r它是空的,正如SHOW TABLES⒏嬖V你:

mysql> SHOW TABLES;
Empty set (0.00 sec)

^y的部分是Q定你的旖Y是什N:你⑿枰什N毂恚和在他中有什N拥牧小

你⑿枰一包含你每物的的表。它可Qpet表,K且它包含,最少,每游锏拿字。因槊字本身不是很有趣,表包含另外的信息。例如,如果在你豢B物的家庭有超^一人,你可能想要列出每游锏闹魅恕D憧赡芤蚕胍例如N和性e的一些基本的描述信息。

年g呢?那可能有趣,但是在一熘写Σ皇且患好事情。年gS著rg流逝而化,@意味著你⒁不嗟馗新你的。相反, 存σ固定值例如生日比^好,那N,o何r你需要年g,你可以以前日期和出生日期之g的差e碛算它。MySQL槿掌谶\算提供了函担因此@K不困y。存Τ錾日期而非年g也有其他c:

你可以煊渺哆@拥娜绽如生成即⒌淼物生日的提示。(如果你J檫@查是c蠢,注意,@c在一商耸灸悴痪靡o它l出生日祝R的客舻沫h境中是同一},因橛算C椭私人j。)
你可以相於日期而不止是前日期碛算年g。例如,如果你在齑λ劳鋈掌冢你能容易算一b物是何r多大死的。
你可能想到pet表中其他有用的其他型信息,但是到目前橹惯@些F在是足蛄耍好字、主人、N,性e、出生和死亡日期。

使用一CREATE TABLEZ句指定你的毂淼牟季郑

mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
    -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

VARCHARname、owner和species列是好的x瘢因榱兄是L的。@些列的L度都不必是相同的,而且不必是20。你可以挑x1到255的任何L度,o哪δ碚f好像最合理。(如果你做了^差的x瘢以後得你需要一更L的字段,MySQL提供一ALTER TABLEZ句。)

游镄员砜梢杂迷S多方法表示,例如,"m"和"f",或也S"male"和"female"。使用字符"m"和"f"是最蔚摹

birth和death列使用DATE型是相明@的x瘛

既然你建了一表,SHOW TABLESa生一些出:

mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                |
+---------------------+

榱蓑C你的表是按你期望的方式被建,使用一DESCRIBEZ句:

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

你能SrDESCRIBE,例如,如果你忘在你表中的列的名字或他是什N型。

8.4.3 b入一毂
在你建表後,你需要充它。LOAD DATA和INSERTZ句用於此。

假定你的物o描述如下。(^察到MySQL期望日期r以YYYY-MM-DD格式;@可能c你T的不同。)

name  owner  species  sex  birth  death  
Fluffy  Harold  cat  f  1993-02-04  
Claws  Gwen  cat  m  1994-03-17  
Buffy  Harold  dog  f  1989-05-13  
Fang  Benny  dog  m  1990-08-27  
Bowser  Diane  dog  m  1998-08-31  1995-07-29  
Chirpy  Gwen  bird  f  1998-09-11  
Whistler  Gwen  bird  1997-12-09  
Slim  Benny  snake  m  1996-04-29  

因槟闶囊空表_始的,充它的一容易方法是建包含槟愕游锔饕恍幸文本文件,然後用一Z句bd文件的热莸奖碇小

你可以建一文本文件“pet.txt”,每行包含一,用定位符(tab)把值分_,K且以在CREATE TABLEZ句中列出的列次序o出。於G失的值(例如未知的性e,或仍然活著的游锏乃劳鋈掌),你可以使用NULL值。榱嗽谀愕奈谋疚募表示@些,使用\N。例如,WhistlerB的看起硐襁@拥(@e在值之g的空白是一的定位字符):

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

榱搜bd文本文件“pet.txt”到pet表中,使用@命令:

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

如果你意,你能明_地在LOAD DATAZ句中指出列值的分隔符和行尾擞,但是缺省是定位符和Q行符。@些取x入文件“pet.txt”的Z句是足虻摹

你想要一次增加一新r,INSERTZ句是有用的。在它最蔚男问剑你槊恳涣刑峁┲担以列在CREATE TABLEZ句被列出的序。假定Diane把一b新}鼠命名Puffball,你可以使用一@INSERTZ句增加一l新:

mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

注意,@e字符串和日期值被指定橐U起淼淖址串。另外,用INSERT,你能直接插入NULL代表不存在的值。你不能使用\N,就像你用LOAD DATA做的那印

倪@例子,你能看到涉及很多的I入用多INSERTZ句而非LOAD DATAZ句bd你的初始。

8.4.4 囊毂z索信息
SELECTZ句被用囊桌子拉出信息。Z句的一般格式是:

SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy

what_to_select指出你想要看到的,@可以是列的一表,或*表明“所有的列”。which_table指出你想要钠z索的表。WHERE子句是可x的,如果它在,conditions_to_satisfy指定行必M足的z索l件。

8.4.4.1 x袼有
SELECT最蔚男问绞囊表中z索每|西:

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

如果你想要考察整表,@N形式的SELECT是很有用的。例如,在你o它bd了你的初始集b以後。它l生r,u@示的出揭示了在你的文件的一e`:在Bowser死了以後,它好像要出生了!教你原淼募易V,你lF正_的出生年是1989,而不是1998。

至少有一些修正它的方法:

文件“pet.txt”改正e`,然後使用DELETE和LOAD DATA弄空表K且再次bd它:
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;

然而, 如果你@幼觯你必重新入Puffball。

用一UPDATEZ句H修正e`:
mysql> UPDATE pet SET birth = "1989-08-31" WHERE name = "Bowser";

如上所示,z索整表是容易的,但是一般你不想那幼觯特e地表得很大r。相反,你通常回答一特e的}更感d趣,在@N情r下你在你想要的信息上指定一些限制。我看一些他回答有P你物的}的x癫樵。

8.4.4.2 x裉囟ㄐ
你能哪愕谋碇须bx裉囟ǖ男小@如,如果你想要C你Bowser的出生日期所做的改,像@泳xBowser的:

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

出C年份F在正_1989,而不是1998。

字符串比^通常是大小些oP的,因此你可以指定名字"bowser"、"BOWSER"等等,查Y果⑹窍嗤的。

你能在任何列上指定l件,不b是name。例如,如果你想要知道哪游镌1998以後出生的,ybirth列:

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

你能M合l件,例如,找出雌性的狗:

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

AND和OR可以混用。如果你@幼觯使用括指明l件如何被分M是一好主意:

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

8.4.4.3 x裉囟列
如果你不想要看到你的表的整行,就命名你感d趣的列,用逗分_。例如,如果你想要知道你的游锸颤Nr候出生的,精xname和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 |
+----------+------------+

找出l碛物,使用@查:

mysql> SELECT owner FROM pet;
+--------+
| owner  |
+--------+
| Harold |
| Gwen  |
| Harold |
| Benny  |
| Diane  |
| Gwen  |
| Gwen  |
| Benny  |
| Diane  |
+--------+

然而,注意到查蔚z索每的owner字段,K且他中的一些出F多次。榱耸馆出p到最少,通^增加PI~DISTINCTz索出每唯一的出:

mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner  |
+--------+
| Benny  |
| Diane  |
| Gwen  |
| Harold |
+--------+

你能使用一WHERE子句把行x衽c列x裣嘟Y合。例如,榱穗b得到狗和的出生日期,使用@查:

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 |
+--------+---------+------------+
8.4.4.4 排序行
你可能已注意到前面的例子中Y果行]有以特定的次序被@示。然而,行以某有意x的方式排序,z查出通常是更容易的。榱伺判蚪Y果,使用一ORDER BY子句。

@e是游锷日,按日期排序:

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

榱艘阅嫘蚺判颍增加DESC(下降 )PI字到你正在排序的列名上:

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

你能在多列上排序。例如,按游锏姆N排序,然後按生日,首先是游锓N中最年p的游铮使用下列查:

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

注意DESCPI~Hm用於o跟在它之前的列名字(birth);species值仍然以升序被排序。

8.4.4.5 日期算
MySQL提供函担你能用绦性谌掌谏系挠算,例如,算年g或提取日期的部分。

榱Q定你的每物有多大,用出生日期和前日期之g的差e算年g。通^Q2日期到天担取差值,K且用365除(在一年e的天):

mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 FROM pet;
+----------+-------------------------------------+
| name    | (TO_DAYS(NOW())-TO_DAYS(birth))/365 |
+----------+-------------------------------------+
| Fluffy  |                                6.15 |
| Claws    |                                5.04 |
| Buffy    |                                9.88 |
| Fang    |                                8.59 |
| Bowser  |                                9.58 |
| Chirpy  |                                0.55 |
| Whistler |                                1.30 |
| Slim    |                                2.92 |
| Puffball |                                0.00 |
+----------+-------------------------------------+

M管查可行,P於它有能被改M的一些事情。首先,如果行以某次序表示,其Y果能更容易被呙琛5诙,年g列的祟}不是很有意x的。

第一}通^增加一ORDER BY name子句按名字排序出斫Q。榱颂理列祟},榱刑峁┮名字以便一不同的撕出F在出中(@被Q橐列e名):

mysql> SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
    -> FROM pet ORDER BY name;
+----------+------+
| name    | age  |
+----------+------+
| Bowser  | 9.58 |
| Buffy    | 9.88 |
| Chirpy  | 0.55 |
| Claws    | 5.04 |
| Fang    | 8.59 |
| Fluffy  | 6.15 |
| Puffball | 0.00 |
| Slim    | 2.92 |
| Whistler | 1.30 |
+----------+------+

榱税age而非name排序出,b要使用一不同ORDER BY子句:

mysql>  SELECT name, (TO_DAYS(NOW())-TO_DAYS(birth))/365 AS age
    ->  FROM pet ORDER BY age;
+----------+------+
| name    | age  |
+----------+------+
| Puffball | 0.00 |
| Chirpy  | 0.55 |
| Whistler | 1.30 |
| Slim    | 2.92 |
| Claws    | 5.04 |
| Fluffy  | 6.15 |
| Fang    | 8.59 |
| Bowser  | 9.58 |
| Buffy    | 9.88 |
+----------+------+

一似的查可以被用泶_定已死亡游锏乃劳瞿挲g。你通^z查death值是否是NULLQ定那些是哪些游铮然後,於那些有非NULL值,算在death和birth值之g的差e:

mysql>  SELECT name, birth, death, (TO_DAYS(death)-TO_DAYS(birth))/365 AS age
    ->  FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name  | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 | 5.91 |
+--------+------------+------------+------+

差使用death IS NOT NULL而非death != NULL,因NULL是特殊的值,@以後解。8.4.4.6 用NULL值工作。

如果你想要知道哪游锵月^生日,怎Nk?於@算,年和天是oP的,你蔚叵胍提取birth列的月份部分。MySQL提供日期部分的提取函担例如YEAR()、MONTH()和DAYOFMONTH()。在@eMONTH()是m合的函怠榱丝此怎庸ぷ鳎\行一蔚牟樵,@示birth和MONTH(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月,那N月值是4K且你ふ以5月出生的游 (5月), 像@樱

mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name  | birth      |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+

然如果前月份是12月,就有c碗s了。你不是b把加1到月份(12)上K且ふ以13月出生的游铮因]有@拥脑路荨O喾矗你ふ以1月出生的游(1月) 。

你甚至可以查以便不管前月份是什N它都能工作。@N方法你不必在查中使用一特定的月份底郑DATE_ADD()允S你把rgg隔加到一o定的日期。如果你把一月加到NOW()值上,然後用MONTH()提取月份部分,Y果a生ふ疑日的月份:

mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));

完成同尤盏囊不同方法是加1以得出前月份的下一月(在使用取模函(MOD)後,如果它前是12,t“@回”月份到值0):

mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MOD(MONTH(NOW()), 12) + 1;

注意,MONTH返回在1和12之g的一底郑且MOD(something,12)返回在0和11之g的一底郑因此必在MOD()以後加1,否t我11月( 11 )跳到1月(1)。

8.4.4.6 NULL值操作
NULL值可能很奇怪直到你T於它。概念上,NULL意味著“]有值”或“未知值”,且它被看作有cc不同的值。榱yNULL,你不能使用算g比^\算符例如=、<或!=。榱苏f明它,下列查:

mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
|    NULL |      NULL |    NULL |    NULL |
+----------+-----------+----------+----------+

很清楚你倪@些比^中得到毫o意x的Y果。相反使用IS NULL和IS NOT NULL操作符:

mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|        0 |            1 |
+-----------+---------------+

在MySQL中,0意味著假而1意味著真。

NULL@犹厥獾奶理是槭颤N,在前面的章中,榱Q定哪游锊辉偈腔钪的,使用death IS NOT NULL而不是death != NULL是必要的。

8.4.4.7 模式匹配
MySQL提供实SQL模式匹配,以及一N基於像Unix用程序如vi、grep和sed的U展正t表_式模式匹配的格式。

SQL的模式匹配允S你使用“_”匹配任何字符,而“%”匹配任意的孔址(包括零字符)。在 MySQL中,SQL的模式缺省是忽略大小的。下面@示一些例子。注意在你使用SQL模式r,你不能使用=或!=;而使用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”Y尾的名字:

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

榱苏页霭含正好5字符的名字,使用“_”模式字符:

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提供的模式匹配的其他型是使用U展正t表_式。你@模式M行匹配yr,使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它是同x~)。

U展正t表_式的一些字符是:

“.”匹配任何的字符。
一字符“[...]”匹配在方括鹊娜魏巫址。例如,“[abc]”匹配“a”、“b”或“c”。榱嗣名字符的一,使用一“-”。“[a-z]”匹配任何小字母,而“[0-9]”匹配任何底帧
“ * ”匹配零或多在它前面的|西。例如,“x*”匹配任何盗康摹x”字符,“[0-9]*”匹配的任何盗康底郑而“.*”匹配任何盗康娜魏|西。
正t表_式是^分大小的,但是如果你希望,你能使用一字符匹配煞N法。例如,“[aA]”匹配小或大的“a”而“[a-zA-Z]”匹配煞N法的任何字母。
如果它出F在被y值的任何地方,模式就匹配(b要他匹配整值,SQL模式匹配)。
榱硕ㄎ灰模式以便它必匹配被y值的_始或Y尾,在模式_始使用“^”或在模式的Y尾用“$”。
榱苏f明U展正t表_式如何工作,上面所示的LIKE查在下面使用REGEXP重:

榱苏页鲆浴b”_^的名字,使用“^”匹配名字的_始K且“[bB]”匹配小或大的“b”:

mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
+--------+--------+---------+------+------------+------------+
| 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”Y尾的名字,使用“$”匹配名字的Y尾:

mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
+--------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat    | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog    | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+

榱苏页霭含一“w”的名字,使用“[wW]”匹配小或大的“w”:

mysql> SELECT * FROM pet WHERE name REGEXP "[wW]";
+----------+-------+---------+------+------------+------------+
| 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      |
+----------+-------+---------+------+------------+------------+

既然如果一正表_式出F在值的任何地方,其模式匹配了,就不必再先前的查中在模式的煞矫娣胖靡通配符以使得它匹配整值,就像如果你使用了一SQL模式那印

榱苏页霭含正好5字符的名字,使用“^”和“$”匹配名字的_始和Y尾,和5“.”例在烧咧g:

mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
+-------+--------+---------+------+------------+-------+
| 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 name REGEXP "^.{5}$";
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen  | cat    | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog    | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+

8.4.4.8 行
旖常用於回答@},“某型的在一表中出F的l度?”例如,你可能想要知道你有多少物,或每位主人有多少物,或你可能想要在你的游锷鲜┬懈鞣N型的普查。

算你碛游锏目底峙c“在pet表中有多少行?”是同拥},因槊物有一。COUNT()函涤捣NULLY果的的浚所以的愕游锏牟樵看起硐襁@樱

mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
|        9 |
+----------+

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

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

注意,使用GROUP BYγowner分M所有,]有它,你得到的一切是一le`消息:

mysql> SELECT owner, COUNT(owner) FROM pet;
ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause

COUNT()和GROUP BYσ愿鞣N方式分你的很有用。下列例子@示出施游锲詹椴僮鞯牟煌方式。

每N游盗浚

mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird    |        2 |
| cat    |        2 |
| dog    |        3 |
| hamster |        1 |
| snake  |        1 |
+---------+----------+

每中性e的游盗浚

mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex  | COUNT(*) |
+------+----------+
| NULL |        1 |
| f    |        4 |
| m    |        4 |
+------+----------+

(在@出中,NULL表示“未知性e”。)

按N和性eM合的游盗浚

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()r,你不必z索整一表。例如, 先前的查,b在狗和上施行r,看起硐襁@樱

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

或,如果你H需要知道已知性e的按性e的游的浚

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

8.4.5 使用多毂
pet表追你有哪物。如果你想要他的其他信息,例如在他一生中事件看Ft或何r後代出生,你需要另外的表。@表像什N呢?

它需要包含物名字因此你知道每事件凫洞游铩
它需要一日期因此你知道事件什Nr候l生的。
需要一字段描述事件。
如果你想要可分事件,有一事件型字段⑹怯杏玫摹
o出了@些考],event表的CREATE TABLEZ句可能看起硐襁@樱

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

就像pet表,最容易的示通^建包含信息的一定位符分隔的文本文件bd初始:

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  

像@友bd:

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

基於你囊呀\行在pet表上的查中W到的,你能绦性event表中的z索;原t是一拥摹5是什Nr候是event表本身不足以回答你可能的}呢?

他有了一C小游r,假定你想要找出每b物的年g。 event表指出何rl生,但是榱擞算母H的年g,你需要她的出生日期。既然它被存υpet表中,榱瞬樵你需要表:

mysql> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
    -> FROM pet, event
    -> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
| name  | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
| Buffy  | 4.12 | 5 puppies, 2 female, 3 male |
| Buffy  | 5.10 | 3 puppies, 3 female        |
+--------+------+-----------------------------+

P於查要注意的准事情:

FROM子句列出表,因椴樵需要乃拉出信息。
M合(Y-join)碜远表的信息r,你需要指定在一表中的怎幽芷ヅ淦渌表的。@很危因樗都有一name列。查使用WHERE子句基於name值砥ヅ2表中的。
因name列出F在表中,引用列r,你一定要指定哪表。@通^把表名附在列名前做到。
你不必有2不同的表绦幸Y。如果你想要⒁表的c同一表的其他M行比^,Y一表到自身有r是有用的。例如,榱嗽谀愕物之中繁殖配偶,你可以用petY自身磉M行相似N的雄雌配Γ

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

在@查中,我楸砻指定e名以便能引用列K且使得每一列引用P於哪表例更直^。

木木 发表于 2004-4-16 02:27

8.5 @得旌捅淼男畔
如果你忘一旎虮淼拿字,或一o定的表的Y是什N(例如,它的列叫什N),怎Nk? MySQL通^提供旒捌渲С值谋淼男畔⒌Z句解Q@}。

你已到了SHOW DATABASES,它列出由服掌鞴芾淼臁榱苏页霎前x窳四欤使用DATABASE()函担

mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+

如果你]x袢魏欤Y果是空的。

榱苏页霎前的彀含什N表(例如,你不能_定一表的名字),使用@命令:

mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| event              |
| pet                |
+---------------------+

如果你想要知道一表的Y,DESCRIBE命令是有很用的;它@示有P一表的每列的信息:

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

Field@示列名字,Type是榱械型,Null表示列是否能包含NULL值,Key@示列是否被索引而Default指定列的缺省值。

如果你在一表上有索引,SHOW INDEX FROM tbl_name生成有P它的信息。

8.6 以批理模式使用mysql
在前面的章中,你交互式地使用mysql入查K且查看Y果。你也可以以批模式\行mysql。榱俗龅竭@些,把你想要\行的命令放在一文件中,然後告Vmysql奈募x取它的入:

shell> mysql < batch-file

如果你需要在命令行上指定B接担命令可能看起硐襁@樱

shell> mysql -h host -u user -p < batch-file
Enter password: ********

你@邮褂mysqlr,你正在建一_本文件,然後绦心_本。

槭颤N要使用一_本?有很多原因:

如果你重偷剡\行查(比如f,每天或每周),把它做成一_本使得你在每次绦兴r避免重新I入。
你能通^拷K_本文件念似的F有的查生成一新查。
你正在_l查r,批模式也是很有用的,特eΧ嘈忻令或多行Z句序列。如果你犯了一e`,你不必重新打入所有一切,b要你的_本砀恼e`,然後告Vmysql再次绦兴。
如果你有一a生很多出的查,你可以通^一分器而不是盯著它翻屏到你屏幕的端磉\行出:
shell> mysql < batch-file | more

你能捕捉出到一文件中M行更一步的理:
shell> mysql < batch-file > mysql.out

你可以散l_本o另外的人,因此他也能\行命令。
一些情r不允S交互地使用,例如, 你囊cron任罩羞\行查r。在@N情r下,你必使用批模式。
你以批模式\行mysqlr,比起你交互地使用它r,其缺省出格式是不同的(更明些)。例如,交互式\行SELECT DISTINCT species FROM petr,出看起硐襁@樱

+---------+
| species |
+---------+
| bird    |
| cat    |
| dog    |
| hamster |
| snake  |
+---------+

但是以批模式\行r,像@樱

species
bird
cat
dog
hamster
snake

如果你想要在批模式中得到交互的出格式,使用mysql -t。榱嘶仫@以出被绦械拿令,使用mysql -vvv。

8.7 p胞胎目的查(例)
在Analytikerna 和 Lentus,我橐大的研究目工程一直在做My和F龉ぷ鳌_@目是Institute of Environmental Medicine at Karolinska Institutet Stockholm 和 the Section on Clinical Research in Aging and Psychology at the University of Southern California的合作目。

p胞胎研究的更多信息可在下列接找到:

[url]http://www.imm.ki.se/TWIN/TWINUKW.HTM[/url]
目的後面部分是用一用Perl和MySQL的web接口砉芾怼

每天晚上所有的被移入一MySQL臁

8.7.1 找出所有非的p胞胎
下列查用Q定lM入目的第二部分:

select
        concat(p1.id, p1.tvab) + 0 as tvid,
        concat(p1.christian_name, " ", p1.surname) as Name,
        p1.postal_code as Code,
        p1.city as City,
        pg.abrev as Area,
        if(td.participation = "Aborted", "A", " ") as A,
        p1.dead as dead1,
        l.event as event1,
        td.suspect as tsuspect1,
        id.suspect as isuspect1,
        td.severe as tsevere1,
        id.severe as isevere1,
        p2.dead as dead2,
        l2.event as event2,
        h2.nurse as nurse2,
        h2.doctor as doctor2,
        td2.suspect as tsuspect2,
        id2.suspect as isuspect2,
        td2.severe as tsevere2,
        id2.severe as isevere2,
        l.finish_date
from
        twin_project as tp
        /* For Twin 1 */
        left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
        left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
        left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
        left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
        /* For Twin 2 */
        left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
        left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
        left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
        left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
        person_data as p1,
        person_data as p2,
        postal_groups as pg
where
        /* p1 gets main twin and p2 gets his/her twin. */
        /* ptvab is a field inverted from tvab */
        p1.id = tp.id and p1.tvab = tp.tvab and
        p2.id = p1.id and p2.ptvab = p1.tvab and
        /* Just the sceening survey */
        tp.survey_no = 5 and
        /* Skip if partner died before 65 but allow emigration (dead=9) */
        (p2.dead = 0 or p2.dead = 9 or
        (p2.dead = 1 and
          (p2.death_date = 0 or
          (((to_days(p2.death_date) - to_days(p2.birthday)) / 365)
            >= 65))))
        and
        (
        /* Twin is suspect */
        (td.future_contact = 'Yes' and td.suspect = 2) or
        /* Twin is suspect - Informant is Blessed */
        (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or
        /* No twin - Informant is Blessed */
        (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or
        /* Twin broken off - Informant is Blessed */
        (td.participation = 'Aborted'
        and id.suspect = 1 and id.future_contact = 'Yes') or
        /* Twin broken off - No inform - Have partner */
        (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))
        and
        l.event = 'Finished'
        /* Get at area code */
        and substring(p1.postal_code, 1, 2) = pg.code
        /* Not already distributed */
        and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
        /* Has not refused or been aborted */
        and not (h.status = 'Refused' or h.status = 'Aborted'
        or h.status = 'Died' or h.status = 'Other')
order by
        tvid;

一些解:

concat(p1.id, p1.tvab) + 0 as tvid
我想要在id和tvab的B接上以底中蚺判颉=Y果加0使得MySQL把Y果作一底帧
列id
@俗R一p胞胎。它是所有表中的一I。
列tvab
@俗Rp胞胎中的一。它有值1或2。
列ptvab
@是tvab一逆。tvab是1,它是2,K且反^硪踩绱恕K存在以保存I入K且使它更容易MySQL化查。
@查表明,怎佑寐Y(p1和p2)耐一表中查找表。在例子中,@被用z查p胞胎的一是否在65q前死了。如果因此,行不返回。

上述所有p胞胎信息存在於所有表中。我在id,tvab烧呱系逆I值(所有表)和在id,ptvab上的I(person_data)以使查更快。

在我的生aC器上(一_200MHz UltraSPARC),@查返回大s 150-200 行K且不超^一秒的rg。

上面所用的表的前凳牵

表  行
person_data  71074
lentus  5291
twin_project  5286
twin_data  2012
informant_data  663
harmony  381
postal_groups  100

8.7.2 @示P於p胞胎近r的表
每一次面以一Qevent的BaY束。下面@示的查被用盹@示按事件M合的所有p胞胎的表。@表明多少p胞胎已完成,多少Φ钠渲兄一已完成而另一拒^了,等等。

select
        t1.event,
        t2.event,
        count(*)
from
        lentus as t1,
        lentus as t2,
        twin_project as tp
where
        /* We are looking at one pair at a time */
        t1.id = tp.id
        and t1.tvab=tp.tvab
        and t1.id = t2.id
        /* Just the sceening survey */
        and tp.survey_no = 5
        /* This makes each pair only appear once */
        and t1.tvab='1' and t2.tvab='2'
group by
        t1.event, t2.event;

页: [1]

Powered by Discuz! Archiver 6.1.0  © 1999-2008 bbs.bitsCN.com