0进入PostgreSQL
1数据库和SQL
1-1数据库是什么
数据库Database(DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合称为数据库
数据库管理系统Database Management System(DBMS):用来管理数据库的计算机系统
DBMS的种类:
- 层次数据库HDB
树状结构,相对于RDB较少使用 - 关系数据库Relational Database,RDB
由行和列组成的二维表来管理数据,使用专门的Structured Query Language(SQL结构化查询语言)对数据进行操作
5种常用的RDBMS:
Oracle Database,SQL server,DB2,PostgreSQL,MySQL - 面向对象数据库
- XML数据库
- 键值存储系统
1-2数据库的结构
RDBMS的常见系统结构:客户端/服务器类型(C/S类型)
客户端:委托方;服务器:受托方(RDBMS)
表的结构
根据SQL语句的内容返回的数据必须是二维表的形式
表的行称为字段;表的行称为记录
1-3SQL概要
SQL用关键字、表名、列名等组合而成的一条语句。
SQL语句的种类:
- DDL(Data definition language,数据定义语言):创建或删除存储数据用的数据库以及数据库中的表等对象
CREATE
DROP
ALTER - DML(Data manipulation language,数据操纵语言):查询或变更表中的记录
SELECT
INSERT
UPDATE
DELETE - DCL(Data control language,数据控制语言):确认或取消对数据库中的数据进行的变更
COMMIT
ROLLBACK
GRANT
REVOKE
SQL的基本书写规则
1.要以分号(;)结尾
2.不区分大小写
为了代码的整洁性,采取下面的规则:
关键字大写
表名的首字母大写
其余(列名等)小写
3.常数的书写方式是固定的
在SQL语句中直接书写的字符串、日期或者数字等称为常数。
含有字符串的时候,使用单引号(')将字符串括起来:'abc'
含有日期时,也需要单引号(')将其括起来,形式有多种:'26 Jan 2010','10/01/26','2010-01-26'
书写数字的时候,不需要任何标识
4.单词之间需要用半角空格或者换行来分隔
1-4表的创建
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));
- 命名规则:只能使用半角英文字母、数字、下划线(_)作为数据库、表和列的名称,且名称必须以字母开头
- 数据类型的指定:
INTEGER型:整数
CHAR型:定长字符串(当字符串达不到指定长度时,用半角空格进行补足)
VARCHAR型:可变长字符串
DATE型:日期 - 约束的设置:
约束是除了数据类型之外,对列中存储的数据进行限制或者追加条件的功能。
NOT NULL约束:该列不能输入空白
主键约束:将product_id设为主键(主键:可以特定一行数据的列)
1-5表的删除和更新
表的删除
DROP TABLE Product;
表定义的更新(添加列或删除列)
ALTER TABLE Product ADD COLUMN product_name_pinyin VARCHAR(100);
ALTER TABLE Product DROP COLUMN product_name_pinyin;
向Product表中插入数据
-- DML:插入数据
BEGIN TRANSACTION;
INSERT INTO Product VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
INSERT INTO Product VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11');
INSERT INTO Product VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL);
INSERT INTO Product VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
INSERT INTO Product VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
INSERT INTO Product VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
INSERT INTO Product VALUES ('0007', '擦菜板', '厨房用具', 880, 790, '2008-04-28');
INSERT INTO Product VALUES ('0008', '圆珠笔', '办公用品', 100, NULL, '2009-11-11');
COMMIT;
表名称的修改
ALTER TABLE Poduct RENAME TO Product;
2查询基础
2-1SELECT语句基础
列的查询
SELECT product_id, product_name, purchase_price
FROM Product;
查询出表中所有的列
SELECT *
FROM Product;
需要注意的是,如果使用星号的话,无法设定列的排列顺序,表会依照CREATE TABLE的顺序对列排序
为列设置别名
SELECT product_id AS id,
product_name AS name,
purchase_price AS price
FROM Product;
SELECT product_id AS "商品编号",
product_name AS "商品名称",
purchase_price AS "进货单价"
FROM Product;
设定中文别名需要用双引号(")括起来
常数的书写
第一列是字符串常数,第二列是数字常数,第三列是日期常数
SELECT '商品' AS string, 38 AS number, '2009-02-24' AS date,
product_id, product_name
FROM Product;
从结果中删除重复行
想知道Product表中保存了哪些商品种类
SELECT DISTINCT product_type
FROM Product;
在使用DISTINCT时,NULL也被视为一类数据
SELECT DISTINCT purchase_price
FROM Product;
在多列之前使用DISTINCT
SELECT DISTINCT product_type, regist_date
FROM Product;
根据WHERE语句来选择记录
SELECT语句通过WHERE子句来指定查询数据的条件
SELECT product_name, product_type
FROM Product
WHERE product_type = '衣服';
首先通过WHERE子句查询出符合指定条件的行,再选取出SELECT语句指定的列;
SQL语句中子句的书写顺序是固定的,WHERE子句必须紧跟在FROM子句后
注释的写法
- 1行注释
书写在“--”之后,只能写在同一行 - 多行注释
书写在“/”和“/”之间,可以跨多行
-- 本SELECT语句会从结果中删除重复行。
SELECT DISTINCT product_id, purchase_price
FROM Product;
/* 本SELECT语句
会从结果中删除重复行。*/
SELECT DISTINCT product_id, purchase_price
FROM Product;
注释还可以插在上两句之间。
SELECT DISTINCT product_id, purchase_price
/* 本SELECT语句
会从结果中删除重复行。*/
FROM Product;
2-2算术运算符和比较运算符
算术运算符
SELECT product_name, sale_price,
sale_price * 2 AS "sale_price_x2"
FROM Product;
算术运算符:+,-,*,/
也可以使用括号
需要注意,有NULL的运算式结果全为NULL
比较运算符
--选取出sale_price列的值不是500的记录
SELECT product_name, product_type
FROM Product
WHERE sale_price <> 500;
--选取出登记日期在2009年9月27日之前的记录
SELECT product_name, product_type, regist_date
FROM Product
WHERE regist_date < '2009-09-27';
也可以对计算结果进行比较
SELECT product_name, sale_price, purchase_price
FROM Product
WHERE sale_price - purchase_price >= 500;
对字符串使用不等号
首先我们创建一个Chars表,如下所示:
--DDL:创建表
CREATE TABLE Chars
(chr CHAR(3) NOT NULL,
PRIMARY KEY (chr));
--DML:插入数据
BEGIN TRANSACTION;
INSERT INTO Chars VALUES ('1');
INSERT INTO Chars VALUES ('2');
INSERT INTO Chars VALUES ('3');
INSERT INTO Chars VALUES ('10');
INSERT INTO Chars VALUES ('11');
INSERT INTO Chars VALUES ('222');
COMMIT;
接着我们选取表中大于‘2’的数据
SELECT chr
FROM Chars
WHERE chr > '2';
执行结果:
这是由于字符串类型的数据在比较时按照字典顺序进行排序:1,10,11,2,222,3
不能与数字的大小顺序混淆
不能对NULL使用比较运算符
--错误的SELECT语句(一条记录也取不出来)
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = NULL;
--选取NULL的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
--选取不为NULL的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NOT NULL;
2-3逻辑运算符
NOT运算符
下面两段语句是等价的
SELECT product_name, product_type, sale_price
FROM Product
WHERE NOT sale_price >= 1000;
SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price < 1000;
AND运算符和OR运算符
AND:同时满足两侧查询条件
OR:两侧查询条件有一个成立
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '厨房用具'
AND sale_price >= 3000;
通过括号强化处理
假设我们需要提取的数据满足:
“商品种类为办公用品” 并且 “登记日期是2009年9月11日或者2009年9月20日”
--将查询条件原封不动地写入条件表达式
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND regist_date = '2009-09-11'
OR regist_date = '2009-09-20';
查询结果和预期不符:
这是由于AND运算符优先于OR运算符造成的。
可以使用半角括号()将OR运算符及其两侧的查询条件括起来
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND ( regist_date = '2009-09-11'
OR regist_date = '2009-09-20');
逻辑运算符与真值
逻辑运算符AND,OR,NOT对比较运算符返回的真值进行操作。
真值:TRUE,FALSE。
含有NULL时的真值
在Product表中,商品“叉子”和“圆珠笔”的purchase_price为NULL,
查询语句为purchase_price = 2800时,显然结果为FALSE;
但是执行查询语句NOT purchase_price = 2800时,结果也是FALSE(不取出NULL所在的值);
它的执行结果是UNKNOWN,这是SQL语言独有的三元逻辑。
真值有:TRUE,FALSE,UNKNOWN。