表中的数据库对象包括列、索引、触发器。在创建表时,必须指定列的名字和数据类型。 表的操作包括创建表、查看表、删除表、修改表。 本文所用的例子和语法均参考《SQL基础教程》第2版。
在数据库名称、表名、列名的命名中,只可以出现1.半角英文字母 2.半角数字 3.下划线,且名称必须以半角英文字母开头。 在同一个数据库中,不能出现相同的表,在同一个表中,列名也不可相同。
在创建表之前,首先要建立一个数据库,在这里,我们首先先建立一个名为shop的数据库,创建方法如下(没有区分大小写):
mysql> create database shop;接着,我们就可以创建表了,通常,创建表的create table语句如下: create table <表名> (<列名1> <数据类型> <该列所需约束>, <列名2> <数据类型> <该列所需约束>, <列名3> <数据类型> <该列所需约束>, <列名4> <数据类型> <该列所需约束>, … <该表的约束1>,<该表的约束2>,……); 需要注意的是,数据类型是创建表时必须要指定的,约束有无都可以,约束也可以在定义列的时候设置,也可以在语句的末尾进行设置,但是 NOT NULL 约束只能以列为单位进行设置。 接下来,我们创建一个名为Product的表。
mysql> create table Product -> (product_id char(4) not null, -> product_name varchar(100) not null, -> product_type varchar(32) not null, -> sale_price integer , -> purchase_price integer , -> regist_date date , -> primary key (product_id)); Query OK, 0 rows affected (0.22 sec)primary key (product_id)是用来给product_id设置主键约束的,即如果把 product_id列指定为主键,就可以通过该列取出特定的数据商品了。但若在product_id中输入了重复数据,就无法取出唯一的特定数据了。
删除的表是无法恢复的,由于后续还要用到Product表,故这里只将语句写出 。
drop table <表名>;
创建了表之后,如果发现少了列数,可以用alter table语句进行列的添加和删除。其中,添加的语句为:
alter table <表名> add column <列的定义>; 我们向Product表中添加product_name_pinyin列,该列可以存储100位的可变长字符串。
mysql> alter table Product add column product_name_pinyin varchar(100);删除列的语句为: alter tabble <表名> drop column <列名>; 接下来,我们删除刚刚添加的列。
mysql> alter table Product drop column product_name_pinyin;需要注意的是,alter table 语句和drop table语句一样,执行之后都无法恢复。
开头的 start transaction语句是开始插入行的指令语句,结尾的commit语句是确定插入行的指令语句。 若想要查看表中的全部数据,则可用
mysql> select * from Product;结果为
+------------+--------------+--------------+------------+----------------+-------------+ | product_id | product_name | product_type | sale_price | purchase_price | regist_date | +------------+--------------+--------------+------------+----------------+-------------+ | 0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-20 | | 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 | | 0003 | 运动T恤 | 衣服 | 4000 | 2800 | NULL | | 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 | | 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 | | 0006 | 叉子 | 厨房用具 | 500 | NULL | 2009-09-20 | | 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 | | 0008 | 圆珠笔 | 办公用品 | 100 | NULL | 2009-11-11 | +------------+--------------+--------------+------------+----------------+-------------+在MySQL中,表明的修改的语句为:
rename table <变更前的名称> to <变更后的名称>;
mysql> rename table Product to produc; Query OK, 0 rows affected (0.11 sec)基本的select语句如下:
select <列名>,…… from <表名>; 接下来,我们尝试从Product表中查询product_id、product_name、purchase_price三列。
mysql> select product_id,product_name,purchase_price from Product; +------------+--------------+----------------+ | product_id | product_name | purchase_price | +------------+--------------+----------------+ | 0001 | T恤衫 | 500 | | 0002 | 打孔器 | 320 | | 0003 | 运动T恤 | 2800 | | 0004 | 菜刀 | 2800 | | 0005 | 高压锅 | 5000 | | 0006 | 叉子 | NULL | | 0007 | 擦菜板 | 790 | | 0008 | 圆珠笔 | NULL | +------------+--------------+----------------+ 8 rows in set (0.00 sec)查询中列的顺序与select语句中的顺序是相同的。 若想要查出表中的所有列,可用*,表示全部的意思,但是若使用星号,则列的显示顺序就是表中的顺序,不能改变。
mysql> select * from product; +------------+--------------+--------------+------------+----------------+-------------+ | product_id | product_name | product_type | sale_price | purchase_price | regist_date | +------------+--------------+--------------+------------+----------------+-------------+ | 0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-20 | | 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 | | 0003 | 运动T恤 | 衣服 | 4000 | 2800 | NULL | | 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 | | 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 | | 0006 | 叉子 | 厨房用具 | 500 | NULL | 2009-09-20 | | 0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-04-28 | | 0008 | 圆珠笔 | 办公用品 | 100 | NULL | 2009-11-11 | +------------+--------------+--------------+------------+----------------+-------------+ 8 rows in set (0.00 sec)但是,当用 select * from product 查询全部时,列名还是原来的列名。 起别名时可是使用中文,需要用双引号括起来(不能为单引号)
mysql> select product_id as "商品编号",product_name as "商品名称",purchase_price as "进货单价" from product; +--------------+--------------+--------------+ | 商品编号 | 商品名称 | 进货单价 | +--------------+--------------+--------------+ | 0001 | T恤衫 | 500 | | 0002 | 打孔器 | 320 | | 0003 | 运动T恤 | 2800 | | 0004 | 菜刀 | 2800 | | 0005 | 高压锅 | 5000 | | 0006 | 叉子 | NULL | | 0007 | 擦菜板 | 790 | | 0008 | 圆珠笔 | NULL | +--------------+--------------+--------------+select子句不仅可以书写列名,也可以书写常数。上述代码中,第一列‘商品’是字符串常数,第2列38是数字常数,第三列’2009-02-24’是日期常数,它们与product_id,product_name列一起被查询出来。
例如查询product表中存了哪些种类的商品。distinct可用来删除重复行。
mysql> select distinct product_type from product; +--------------+ | product_type | +--------------+ | 衣服 | | 办公用品 | | 厨房用具 | +--------------+在使用distinct时,null也被视为一类数据,存在于多行中时也会合并成为一条null数据。对purchase_price进行去重。
mysql> select distinct purchase_price from product; +----------------+ | purchase_price | +----------------+ | 500 | | 320 | | 2800 | | 5000 | | NULL | | 790 | +----------------+distinct也可将多列数据去重,去掉的是每一列都一样的数据。
mysql> select distinct product_type,regist_date from product; +--------------+-------------+ | product_type | regist_date | +--------------+-------------+ | 衣服 | 2009-09-20 | | 办公用品 | 2009-09-11 | | 衣服 | NULL | | 厨房用具 | 2009-09-20 | | 厨房用具 | 2009-01-15 | | 厨房用具 | 2008-04-28 | | 办公用品 | 2009-11-11 | +--------------+-------------+注:distinct关键字只能用在第一个列名之前。
前面的例子都是将表中存储的数据全部都选取出来,但是实际中,我们通常选出满足条件的数据即可。MySQL中用where语句来选择满足条件的数据。
select <列名>,…… from <表名> where <条件表达式>; 下面我们选取product_type列为‘衣服’的记录。同时将product_name也显示出来。
mysql> select product_name,product_type from product where product_type = '衣服'; +--------------+--------------+ | product_name | product_type | +--------------+--------------+ | T恤衫 | 衣服 | | 运动T恤 | 衣服 | +--------------+--------------+执行顺序是首先通过where子句查询出符合指定条件的记录,然后再选取出select语句指定的列。 也可以不选取出作为查询条件的列。
mysql> select product_name from product where product_type = '衣服'; +--------------+ | product_name | +--------------+ | T恤衫 | | 运动T恤 | +--------------+需要注意的是,where语句要放在from子句之后。
书写在“–”之后,只能卸载同一行。中英文都可。
mysql> -- 此语句用来产出重复行其中,–之后的空格一定要有,不然会报错。
书写在“/星” 和“星/”之间,可以用于多行注释。
mysql> /* 本select语句, /*> 会从结果中删除重复行 */注释语句可放在任何位置。
运算以行为单位执行。+、—、*、/为算术运算符。 例如将sale_price列乘2倍命名为sale_price_*2.
mysql> select product_name,sale_price, -> sale_price *2 as 'sale_price_*2' -> from product; +--------------+------------+---------------+ | product_name | sale_price | sale_price_*2 | +--------------+------------+---------------+ | T恤衫 | 1000 | 2000 | | 打孔器 | 500 | 1000 | | 运动T恤 | 4000 | 8000 | | 菜刀 | 3000 | 6000 | | 高压锅 | 6800 | 13600 | | 叉子 | 500 | 1000 | | 擦菜板 | 880 | 1760 | | 圆珠笔 | 100 | 200 | +--------------+------------+---------------+在运算时,要特别注意含有null的运算。所有包含null的计算结果都为null。5/0会报错,但是null/0结果为null。
在select语句中,from真的必须要有么?在Oracle中是必须要有的,但是在sql server、posegresql、mysql中可以没有。 例如:
mysql> select (100+200)*3 as calculation; +-------------+ | calculation | +-------------+ | 900 | +-------------+例如选择sale_price为500的记录。
mysql> select product_name,product_type from product where sale_price=500; +--------------+--------------+ | product_name | product_type | +--------------+--------------+ | 打孔器 | 办公用品 | | 叉子 | 厨房用具 | +--------------+--------------+=用来比较两边的列或者值的符号是否相等。用<>表示不等于。例如选取sale_price不为500的记录。
mysql> select product_name,product_type from product where sale_price<>500; +--------------+--------------+ | product_name | product_type | +--------------+--------------+ | T恤衫 | 衣服 | | 运动T恤 | 衣服 | | 菜刀 | 厨房用具 | | 高压锅 | 厨房用具 | | 擦菜板 | 厨房用具 | | 圆珠笔 | 办公用品 | +--------------+--------------+ 运算符含义=和…相等<>和…不相等>=大于等于…>大于…<=小于等于…<小于…这些运算符可以对字符,数字和日期等几乎所有的数据类型的列和值进行比较。 例如选取出sale_price大于等于1000的记录以及regist_date在2009年9月27日之间的记录。
mysql> select product_name,product_type,sale_price from product where sale_price >=1000; +--------------+--------------+------------+ | product_name | product_type | sale_price | +--------------+--------------+------------+ | T恤衫 | 衣服 | 1000 | | 运动T恤 | 衣服 | 4000 | | 菜刀 | 厨房用具 | 3000 | | 高压锅 | 厨房用具 | 6800 | +--------------+--------------+------------+ mysql> select product_name,product_type,regist_date from product where regist_date <'2009-09-27'; +--------------+--------------+-------------+ | product_name | product_type | regist_date | +--------------+--------------+-------------+ | T恤衫 | 衣服 | 2009-09-20 | | 打孔器 | 办公用品 | 2009-09-11 | | 菜刀 | 厨房用具 | 2009-09-20 | | 高压锅 | 厨房用具 | 2009-01-15 | | 叉子 | 厨房用具 | 2009-09-20 | | 擦菜板 | 厨房用具 | 2008-04-28 | +--------------+--------------+-------------+注意,null的值没有用于比较,所以没有输出带有null的行。 找出sale_price-purchase_price>500的记录。
mysql> select product_name,sale_price,purchase_price from product where sale_price-purchase_price>=500; +--------------+------------+----------------+ | product_name | sale_price | purchase_price | +--------------+------------+----------------+ | T恤衫 | 1000 | 500 | | 运动T恤 | 4000 | 2800 | | 高压锅 | 6800 | 5000 | +--------------+------------+----------------+带有null的没有参与运算。
首先,将1,2,3,10,11,222作为字符串插入chars表中。
mysql> -- DDL:创建表 mysql> create table chars -> (chr char(3) not null,primary key(chr)); mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> insert into chars values ('1'); mysql> insert into chars values ('2'); mysql> insert into chars values ('3'); mysql> insert into chars values ('10'); mysql> insert into chars values ('11'); mysql> insert into chars values ('222'); mysql> commit; --结果为 mysql> select * from chars; +-----+ | chr | +-----+ | 1 | | 10 | | 11 | | 2 | | 222 | | 3 | +-----+选择出大于’2’ 的字符串。
mysql> select chr from chars where chr > '2'; +-----+ | chr | +-----+ | 222 | | 3 | +-----+字符串类型的数据原则上按照字典顺序进行比较,以相同字符开头的单词比不同字符开头的单词更相近,所以插入数据的排序方式如上,相同的挨在一起。
筛选出purchase_price不等于2800的记录。
mysql> select product_name,purchase_price from product where purchase_price<>2800; +--------------+----------------+ | product_name | purchase_price | +--------------+----------------+ | T恤衫 | 500 | | 打孔器 | 320 | | 高压锅 | 5000 | | 擦菜板 | 790 | +--------------+----------------+由于叉子和圆珠笔这两条记录的purchase_price为null(不明),故无法判断是否为2800,那么如何筛选出purchase_price为null的记录呢?我们用purchase_price=null试一下可行否。
mysql> select product_name,purchase_price from product where purchase_price=null; Empty set (0.00 sec)一条记录都没有提取出来。用purchase_price<>null也是0条。因此SQL语言中有专门提供判断是否为null的语句—is null 运算符。
mysql> select product_name,purchase_price from product where purchase_price is null; +--------------+----------------+ | product_name | purchase_price | +--------------+----------------+ | 叉子 | NULL | | 圆珠笔 | NULL | +--------------+----------------+同理,选取不是null的记录用 is not null
mysql> select product_name,purchase_price from product where purchase_price is not null; +--------------+----------------+ | product_name | purchase_price | +--------------+----------------+ | T恤衫 | 500 | | 打孔器 | 320 | | 运动T恤 | 2800 | | 菜刀 | 2800 | | 高压锅 | 5000 | | 擦菜板 | 790 | +--------------+----------------+SQL中的逻辑运算是包含对真(true)、假(false)和不确定(unknown)进行运算的三值逻辑。
在之前的内容中,我们有介绍过,表达“不是”的否定条件时需要用到<>运算符,在接下来的介绍中,我们使用not运算符,此运算符的使用范围更广。not不能单独使用,需要和其他查询条件组合起来使用。 在筛选出sale_price<1000的记录时,不仅可以使用<1000,也可使用 not>=1000,两者筛选出的结果相同。
mysql> select product_name,product_type,sale_price from product where not sale_price >=1000; +--------------+--------------+------------+ | product_name | product_type | sale_price | +--------------+--------------+------------+ | 打孔器 | 办公用品 | 500 | | 叉子 | 厨房用具 | 500 | | 擦菜板 | 厨房用具 | 880 | | 圆珠笔 | 办公用品 | 100 | +--------------+--------------+------------+使用and和or运算符可以多多个查询条件进行组合。and在两侧查询都为真时才成立,or只要其中一个成立就成立。 下面我们筛选出product_type='厨房用具’并且sale_price>=3000的商品。
mysql> select product_name,purchase_price from product where product_type='厨房用具' and sale_price>=3000; +--------------+----------------+ | product_name | purchase_price | +--------------+----------------+ | 菜刀 | 2800 | | 高压锅 | 5000 | +--------------+----------------+接下来,我们比较以下使用 or以后的运算结果。
mysql> select product_name,purchase_price from product where product_type='厨房用具' or sale_price>=3000; +--------------+----------------+ | product_name | purchase_price | +--------------+----------------+ | 运动T恤 | 2800 | | 菜刀 | 2800 | | 高压锅 | 5000 | | 叉子 | NULL | | 擦菜板 | 790 | +--------------+----------------+下面我们筛选出满足 以下条件的记录: 商品种类为办公用品 并且 登记日期时2009年9月11日或者2009年9月20日 查看表,满足此条件的只有打孔器。 我们这样写条件查询:
mysql> select product_name,product_type,regist_date from product where product_type='办公用品' and regist_date='2009-09-11' or regist_date='2009-09-20'; +--------------+--------------+-------------+ | product_name | product_type | regist_date | +--------------+--------------+-------------+ | T恤衫 | 衣服 | 2009-09-20 | | 打孔器 | 办公用品 | 2009-09-11 | | 菜刀 | 厨房用具 | 2009-09-20 | | 叉子 | 厨房用具 | 2009-09-20 | +--------------+--------------+-------------+显然,这样的结果不是我们想要的。其错误原因是and运算符优先于or造成的。and运算符进行的逻辑运算称为逻辑积,or运算符进行的逻辑运算称为逻辑和。所以,前两句逻辑会先执行,接着再执行最后一句。使用括号可解决这以问题。
mysql> select product_name,product_type,regist_date from product where product_type='办公用品' and (regist_date='2009-09-11' or regist_date='2009-09-20'); +--------------+--------------+-------------+ | product_name | product_type | regist_date | +--------------+--------------+-------------+ | 打孔器 | 办公用品 | 2009-09-11 | +--------------+--------------+-------------+null对应的逻辑是不确定(unknown)。
PQP AND Q真不确定不确定假不确定假不确定不确定不确定 PQP OR Q真不确定真假不确定不确定不确定不确定不确定如何记忆呢?假设 真>不确定>假,则在and中,偏向弱的,在or中,偏向强的。
