下面是一些学习如何用MySQL解决一些常见问题的例子。
一些例子使用数据库表“shop”,包含某个商人的每篇文章(物品号)的价格。假定每个商人的每篇文章有一个单独的固定价格,那么(物品,商人)是记录的主键。
你能这样创建例子数据库表:
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 |
+---------+--------+-------+
3.1 列的最大值
“最大的物品号是什么?”
SELECT MAX(article) AS article FROM shop
+---------+
| article |
+---------+
| 4 |
+---------+
3.2 拥有某个列的最大值的行
“找出最贵的文章的编号、商人和价格”
在ANSI-SQL中这很容易用一个子查询做到:
SELECT article, dealer, price
FROM shop
WHERE price=(SELECT MAX(price) FROM shop)
在MySQL中(还没有子查询)就用2步做到:
用一个SELECT语句从表中得到最大值。
使用该值编出实际的查询:
SELECT article, dealer, price
FROM shop
WHERE price=19.95
另一个解决方案是按价格降序排序所有行并用MySQL特定LIMIT子句只得到的第一行:
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1
注意:如果有多个最贵的文章( 例如每个19.95),LIMIT解决方案仅仅显示他们之一!
3.3 列的最大值:按组:只有值
“每篇文章的最高的价格是什么?”
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 |
+---------+-------+
3.4 拥有某个字段的组间最大值的行
“对每篇文章,找出有最贵的价格的交易者。”
在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)。见3.4 拥有某个域的组间最大值的行。
对每篇文章,得到对应于存储最大价格的行。
这可以很容易用一个临时表做到:
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表,你也必须锁定“tmp”表。
“它能一个单个查询做到吗?”
是的,但是只有使用我称之为“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 |
+---------+--------+-------+
最后例子当然能通过在客户程序中分割连结的列使它更有效一点。
3.5 使用外键
不需要外键联结2个表。
MySQL唯一不做的事情是CHECK以保证你使用的键确实在你正在引用表中存在,并且它不自动从有一个外键定义的表中删除行。如果你象平常那样使用你的键值,它将工作得很好!
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 <> 'white';
+----+-------+--------+-------+
| id | style | color | owner |
+----+-------+--------+-------+
| 4 | dress | orange | 2 |
| 5 | polo | red | 2 |
| 6 | dress | blue | 2 |
+----+-------+--------+-------+
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
相关专题
·MySQL数据备份 (1709篇文章)
·MySQL (1605篇文章)
·SQL Server 索引和查询专题 (2717篇文章)
·MySQL安全 (8548篇文章)
·城域网专题 (6839篇文章)
·MySQL基础 (154篇文章)
·MySQL (1605篇文章)
·SQL Server 索引和查询专题 (2717篇文章)
·MySQL安全 (8548篇文章)
·城域网专题 (6839篇文章)
·MySQL基础 (154篇文章)
·JSP连接Mysql数据库 (1337次浏览)
·安装和卸载MySQL的Windows系统服务 (1) (1227次浏览)
·SQL注入实战---利用“dbo”获得SQL管理权限 (1226次浏览)
·SQL注入漏洞全接触--进阶篇(二) (1194次浏览)
·触发器概述 (456次浏览)
·在Linux异构网络中备份MYSQL数据库(图) (330次浏览)
·送给新手---MySQL使用的前奏 (77次浏览)
·常用MySQL的命令集锦 (40次浏览)
·Ubuntu 7.04系统上安装Apache PHP MySQL (35次浏览)
·轻松接触MySQL数据库支持的3个引擎 (26次浏览)
·安装和卸载MySQL的Windows系统服务 (1) (1227次浏览)
·SQL注入实战---利用“dbo”获得SQL管理权限 (1226次浏览)
·SQL注入漏洞全接触--进阶篇(二) (1194次浏览)
·触发器概述 (456次浏览)
·在Linux异构网络中备份MYSQL数据库(图) (330次浏览)
·送给新手---MySQL使用的前奏 (77次浏览)
·常用MySQL的命令集锦 (40次浏览)
·Ubuntu 7.04系统上安装Apache PHP MySQL (35次浏览)
·轻松接触MySQL数据库支持的3个引擎 (26次浏览)
·2007开源数据库MySQL:将展翅高飞 10-31
·mysql导入数据相关的一些东西 10-31
·轻松掌握在 Mac OS X中安装MySQL 10-25
·建立MySQL的SSL连接通道 10-17
·帮助你如何迅速优化你MySQL数据库性能 10-09
·无法远程登入MySQL数据库的几种解决办法 10-09
·带你完全认识MySQL数据库中Show命令用法 10-09
·安装MySQL5.0后出现1607异常的解决办法 10-09
·快速掌握 Mysql数据库对文件操作的封装 10-09
·MySQL 5.0.16乱码问题的解决方法 10-09
·mysql导入数据相关的一些东西 10-31
·轻松掌握在 Mac OS X中安装MySQL 10-25
·建立MySQL的SSL连接通道 10-17
·帮助你如何迅速优化你MySQL数据库性能 10-09
·无法远程登入MySQL数据库的几种解决办法 10-09
·带你完全认识MySQL数据库中Show命令用法 10-09
·安装MySQL5.0后出现1607异常的解决办法 10-09
·快速掌握 Mysql数据库对文件操作的封装 10-09
·MySQL 5.0.16乱码问题的解决方法 10-09
最新论坛文章
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
站内频道文章精选
百度推荐,商机无限
搜索您感兴趣的内容



