常用SQL操作(MySQL或PostgreSQL)与相关数据库概念

时间:2023-03-10 02:38:15
常用SQL操作(MySQL或PostgreSQL)与相关数据库概念

本文对常用数据库操作及相关基本概念进行总结:MySQL和PostgreSQL对SQL的支持有所不同,大部分SQL操作还是一样的。

选择要用的数据库(MySQL):use database_name;

help show;

显示可用的数据库列表:show databases;

显示一个数据库内可用的表的列表:show tables;

显示表列:show columns from 一个表名; /describe 表名;  示例:show columns from customers;    describe customers;

显示广泛的服务器状态信息:show status;

显示创建特定数据库或表的mysql语句:show create databases;  show create table;

显示授予用户的安全权限:show grants;

显示服务器错误或警告消息:show errors;   show warnings;

help select;

select 从一个或多个表中检索一个或多个数据列;

select 列(字段) from 表名;            select prod_name from products;

检索多个列

select prod_id, prod_name, prod_price from products;

检索所有列

select  * from products;

select vend_id from products;

检索不同的行

select distinct vend_id from products;

限制结果

select prod_name from products limit 5;

使用完全限定的列名

select  products.prod_name  from products;

使用完全限定的表名

select  products.prod_name  from  crashcouse.products;

排序检索数据

为了明确地排序用select语句检索出的数据,可使用order by字句;

order by 字句取一个或多个列的名字,据此对输出进行排序。如下:

select prod_name from products order by prod_name;

用非检索的列排序数据是完全合法的。

按多个列排序

为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列是所做的那样)

select prod_id, prod_price, prod_name from products order by prod_price , prod_name;

指定排序方向(默认升序排序从A到Z),降序排序必须指定desc关键字

desc关键字只应用到直接位于其前面的列名。

select prod_id, prod_price , prod_name from products order by prod_price desc;

用多个列排序

select prod_id, prod_price, prod_name from products order by prod_price desc, prod_name;

在多个列上降序排序:如果想在多个列上进行降序排序,必须对每个列指定desc关键字

与desc相反的关键字是asc(ascending),在排序是可以指定他,升序是默认的

使用order by 和limit的组合,能够找出一个列中最高或最低的值。

order by 子句应位于from子句,limit子句应位于order by 子句后面

select  prod_price from products  order by  prod_price desc  limit 1;

过滤数据:使用select 语句的where 子句指定搜索条件(也称为过滤条件filter condition)

在select语句中,数据根据where子句中指定的搜索条件进行过滤。where子句在表名(from子句)之后给出,如下所示:

select prod_name, prod_price from products where prod_price = 2.50;

在同时使用order by 和 where子句时,应该让order by 位于where之后

检查单个值 单引号用来限定字符串

select prod_name, prod_price from products where prod_name = ‘fuses’;

select prod_name , prod_price from products where prod_price < 10;

select prod_name , prod_price from products where prod_price < =10;

不匹配检查<>

select vend_id, prod_name from products where vend_id <> 1003;

select vend_id, prod_name from products where vend_id  != 1003;

范围值检查:between

select prod_name,prod_price from products where prod_price between 5 and 10;

空值检查 IS NULL

select prod_name from products where prod_price IS NULL;

select cust_id from customers where cust_email IS NULL;

数据过滤:组合where子句 and指示DBMS只返回满足所有给定条件的行

为了通过不止一个列进行过滤,可使用and操作符给where子句附件条件

select prod_id, prod_price, prod_name from products where vend_id =  1003 and prod_price <=10;

每添加一个过滤条件就使用一个and。

or操作指示检索匹配任一条件的行。

select prod_name, prod_price from products where vend_id =1002 or vend_id =1003

SQL在处理OR操作符前,优先处理AND操作符。

可以使用圆括号明确地分组相应的操作符。

select prod_name,prod_price from products where (vend_id = 1002 OR vend_id =1003) AND prod_price >=10;

IN操作符:用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都在圆括号中。

select prod_name,prod_price from products where vend_id IN (1002,1003) order by prod_name;

IN操作符完成与OR相同的功能

select prod_name,prod_price from products where vend_id = 1002 OR vend_id = 1003 order by prod_name;

where子句中的not操作符有且只有一个功能:否定它之后所跟的任何条件的关键字。

select prod_name,prod_price  from products where vend_id NOT IN (1002,1003) order by prod_name;

用通配符进行过滤

通配符:用来匹配值的一部分的特殊字符。

搜索模式:由字面值、通配符或两者组合构成的搜索条件。

通配符是SQL的where子句中有特殊含义的字符,SQL支持几种通配符

为在搜索子句中使用通配符,必须使用LIKE操作符。

百分号(%)通配符:%表示任何字符出现任意次数。

select prod_id, prod_name from products where prod_name LIKE ‘jet%’;

select prod_id prod_name from products where prod_name LIKE ‘%anvil%’;

select prod_name from products where prod_name LIKE ‘s%s’;

下划线(_)通配符:下划线用途与%一样,下划线只匹配单个字符而不是多个字符。

select prod_id, prod_name from products where prod_name LIKE ‘_ ton anvil’;

select prod_id, prod_name from products where prod_name LIKE ‘% ton anvil’;

用正则表达式进行搜索

正则表达式是用来匹配文本的特殊的串(字符集合)

基本字符匹配

select prod_name from products where prod_name regexp ‘1000’ order by prod_name;

除关键LIKE被regexp替代外,这条语句看上去像使用LIKE的语句,它告诉MySQL:regexp后跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理。

select prod_name from products where prod_name regexp ‘.1000’ order by prod_name;

这里使用了正则表达式 .1000, .是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符。

|为正则表达式的OR操作符,如下所示:

select prod_name from products where prod_name regexp ‘1000|2000’ order by prod_name;

匹配几个字符之一

匹配特定的字符,可通过指定一组用[ 和 ]括起来的字符来完成。

select prod_name from products where prod_name regexp ‘[123] Ton’ order by prod_name;

[123]定义一组字符,它的意思是匹配1或2或3

为否定一个字符集,在集合的开始处放置一个^即可,[^123]匹配除这些字符外的任何东西。

匹配范围:集合可用来定义要匹配的一个或多个字符。

[0123456789], [0-9]匹配数字0到9

[a-z]匹配任意字母字符

select prod_name from products where prod_name regexp ‘[1-5] Ton’ order by prod_name;

为了匹配特殊字符必须用\\为前导。\\- 表示查找 - ,\\. 表示查找 . 。

select vend_name from vendors where vend_name regexp ‘\\.’ order by vend_name;

创建计算字段

计算字段并不实际存在于数据库表中,是运行时在select语句内创建的。

拼接字段:

拼接:将值联接到一起构成单个值。解决办法:把两个列拼接起来,在MySQL的select语句中,可以使用Concat()函数来拼接两个列。多数DBMS使用+或||来实现拼接。

Concat()拼接串,即把多个串连接起来形成一个较长的串。Concat()需要一个或多个指定的串,各个串之间用逗号分隔。

select Concat(vend_name, ‘ (‘, vend_conntry, ‘) ‘ ) from vendors order by vend_name;

通过删除数据右侧多余的空格来整理数据,可以使用MySQL的RTrim()函数来完成,如下:

select Concat(RTrim(vend_name), ‘ (‘, RTrim(vend_country), ‘)’) from vendors order by vend_name;

RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理。

MySQL还支持LTrim()去掉左边的空格以及Trim()去掉串左右两边的空格。

使用别名:

SQL支持别名。别名(alias)是一个字段或值的替换名。别名用AS关键字赋予。

select Concat(RTrim(vend_name), ‘ (‘, RTrim(vend_country), ‘)’) AS vend_title from vendors order by vend_name;

执行算术计算

select prod_id, quantity, item_price  from  orderitems where order_num = 20005;

select prod_id,

quantity,

item_price, quantity * item_price AS expended_price

from  orderitems

where order_num = 20005;

如何测试计算:

select提供了测试和试验函数与计算的一个很好的办法。

select 可以省略from子句以便简单地访问和处理表达式。

如:select 3 * 2;将返回6,select Trim(‘abc’);将返回abc.

select Now()利用Now()函数返回当前日期和时间。

使用数据处理函数

文本处理函数 Upper()函数(将文本转换为大写)

select vend_name, Upper(vend_name) AS vend_name_upcase

from vendors

order by vend_name;

常用的文本处理函数

Left( ) 返回串左边的字符

Length( ) 返回串的长度

Locate( )  找出串的一个子串

Lower( )   将串转换为小写

LTrim( )     去掉串左边的空格

Right( )     返回串右边的字符

RTrim( )   去掉串右边的空格

Soundex( ) 返回串的SOUNDEX值:将任何文本串转换为描述其语音表示的字母数字模式,

使得能对串进行发音比较二不是字母比较。

SubString( ) 返回子串的字符

Upper( )             将串转换为大写

select cust_name, cust_contact from customers where Soundex(cust_contact) = Soundex(‘Y Lie’);

时间和日期处理函数

常用日期和时间处理函数

AddDate( )                          增加一个日期(天,周等)

AddTime( )                          增加一个时间(时,分等)

CurDate( )                           返回当前日期

CurTime( )                           返回当前时间

Date( )                                  返回当前日期时间的日期部分

DateDiff( )                           计算两个日期之差

Date_Add( )                        高度灵活的日期运算函数

Date_Format( )                  返回一个格式化的日期或时间串

Day( )                                    返回一个日期的天数部分

DayOfWeek( )                              对于一个日期,返回对应的星期几

Hour( )                                           返回一个时间的小时部分

Minute( )                                       返回一个时间的分钟部分

Month( )                                        返回一个时间的月份部分

Now( )                                          返回当前日期和时间

Second( )                                       返回一个时间的秒部分

Time( )                                           返回一个日期时间的时间部分

Year( )                                            返回一个日期的年份部分

select cust_id, order_num from orders

where order_date = ‘2005-09-01’;

Date(order_date)指示MySQL仅提取列的日期部分,更可靠的select语句为:

select cust_id, order_num from orders

where Date(order_date) = ‘2005-09-01’;

select cust_id, order_num from orders

where Date(order_date) between ‘2005-09-01’ and ‘2005-09-30’;

select cust_id, order_num from orders

where Year(order_date) = 2005 and Month(order_date) = 9 ;

数值处理函数:

Abs( )                           返回一个数的绝对值

Cos( )                           返回一个角度的余弦

Exp( )                           返回一个数的指数值

Mod( )                         返回除操作的余数

Pi( )                              返回圆周率

Rand( )                        返回一个随机数

Sin( )                   返回一个角度的正弦

Sqrt( )                          返回一个数的平方根

Tan( )                           返回一个数的正切

汇总数据

聚集函数:检索数据,以便分析和报表生成 产生 汇总信息

确定表中行数(或者满足某个条件或包含某个特定值的行数)

获得表中行组的和

找出表列(或所有行或某些特定的行)的最大值,最小值和平均值

MySQL的5个聚集函数

聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数

SQL聚集函数

AVG( )                返回某列的平均值

COUNT( )          返回某列的行数     确定表中行的数目或符合特定条件的行的数目

MAX( )               返回某列的最大值

MIN( )                返回某列的最小值

SUM( )               返回某列值之和

AVG( )(只用于单个列) 通过对表中行数计算并计算特定列值之和,求得该列的平均值。

AVG( )可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。

select AVG(prod_price) AS avg_price from products;

select AVG(prod_price) AS avg_price from products where vend_id = 1003;

COUNT(*)对表中行的数目进行计数,不管列表中包含的是空值(NULL)还是非空值。

COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。

下面的例子返回customers表中客户的总数:COUNT(*)对所有行计数

select COUNT(*) AS num_cust         from customers;

select COUNT(cust_email) AS num_cust         from customers;

select MAX(prod_price) AS max_price             from products;

select MIN(prod_price) AS min_price      from products;

select SUM(quantity) AS items_ordered from orderitems where order_num = 20005;

select SUM(item_price * quantity) AS total_price from orderitems where order_name = 20005;

聚集不同值

对所有的行执行计算,指定ALL参数或不给参数(因为ALL是默认行为);

只包含不同的值,指定DISTINCT参数。

平均值只考虑各个不同的价格:

select AVG(DISTINCT prod_price) AS avg_price from products where vend_id = 1003;

组合聚集函数:select 语句可根据需要包含多个聚集函数。

select COUNT(*) AS num_items,

MIN(prod_price) AS price_min,

MAX(prod_price) AS price_max,

AVG(prod_price) AS price_avg,

from products;

联结(join):是一种机制,用来在一条select语句中关联表,称之为联结;使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。

借助联结(join)可以用单条select语句检索出存储在多个表中的数据

联结不是物理实体,它在实际的数据库表中不存在;联结有MySQL根据需要建立,它存在于查询的执行当中。

创建联结

联结的创建非常简单,规定要联结的所有表以及它们如何关联即可。如下:

select vend_name, prod_name, prod_price

from vendors, products

where vendors.vend_id = products.vend_id order by vend_name, prod_name;

完全限定列名:用一个点分隔的表名和列名。(如vendors.vend_id);

如果饮用一个没有用表名限制的具有二义性的列名,MySQL将返回错误。

笛卡尔积:由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。

select vend_name, prod_name, prod_price

from vendors,products   order by  vend_name,prod_name;

应该保证所有联结都有where子句,否则MySQL将返回比想要的数据多的多的数据。

内联结

select vend_name,prod_name,prod_price

from vendors INNER JOIN products

ON vendors.vend_id = products.vend_id;

select vend_name, prod_name, prod_price

from vendors, products

where vendors.vend_id = products.vend_id order by vend_name, prod_name;的功能相同

联结多个表:首先列出所有表,然后定义表之间的关系。例如:

select prod_name, vend_name, prod_price, quantity

from orderitems, products, vendors

where products.vend_id = vendors.vend_id

AND orderitems.prod_id = products.prod_id

AND order_num = 2005;

select cust_name, cust_contact

from          customers, orders, orderitems

where customers.cust_id = orders.cust_id

AND orderitems.order_num = orders.order_num

AND prod_id = ‘TNT2’;

创建高级联结(16)

给表起别名的语法如下:

select Concat(RTrim(vend_name), ‘ (‘, RTrim(vend_country), ‘)’ ) AS

vend_title

from vendors

order by vend_name;

给表名起别名:可以缩短SQL语句,允许在单条select语句中多次使用相同的表。例如:

select cust_name, cust_contact

from customers AS c, orders AS o, orderitems AS oi

where c.cust_id = o.cust_id

AND oi.order_num = o.order_num

AND prod_id = ‘TNT2’;

表别名只在查询执行中使用。表别名不返回到客户机。

自联结

select prod_id, prod_name

from products

where vend_id = (select vend_id

from products

where prod_id = ‘DTNTR’);

使用联结的相同查询:

select p1.prod_id, p1.prod_name

from products AS p1, products AS p2

where p1.vend_id = p2.vend_id

AND p2.prod_id = ‘DTNTR’;

21创建和操纵表

一般有两种创建表的方法:

使用具有交互式创建和管理表的工具

也可以直接使用MySQL语句操作。

下面的MySQL语句创建本书中所用的customers表:

create table customers   IF NOT EXISTS

(

cust_id              int            not null     auto_increment,

cust_name       char(50)   not null,

cust_address   char(50)   null,

cust_city           char(50)   null,

cust_state        char(5)     null,

cust_zip            char(10)   null,

cust_country   char(50)   null,

cust_contact   char(50)   null,

cust_email       char(255) null,

primary    key   (cust_id)

)ENGINE = InnoDB;

create table orders

(

order_num                int              not null auto_increment,

order_date                datetime not null,

cust_id                        int              not null,

primary   key (order_num)

)ENGINE = InnorDB;

create table venders

(        vend_id             int              not null     auto_increment,

vend_name      char(50)   not null,

vend_address  char(50)   null,

vend_city          char(50)   null,

vend_state       char(5)     null,

vend_zip           char(10)   null,

vend_country  char(50)   null,

primary    key (vend_id)

)ENGINE = InnoDB;

由多个列组成的主键:

create table orderitems

(

order_num                int                       not null,

order_item                int                       not null,

prod_id                       char(10)            not null,

quantity                      int                       not null,

item_price                 decimal(8,2)     not null,

primary key      (order_num,    order_item)

)ENGINE  =InnoDB;

每个表只允许一个auto_increment列,而且它必须被索引(如,通过使它成为主键)。

可使用last_insert_id( )函数获得这个值,如下所示:

select last_insert_id( );   此语句返回最后一个auto_increment值,然后可以将它用于后续的MySQL语句。

指定默认值(如果在插入行是没有给出值,MySQL允许指定此时使用的默认值。默认值用create table 语句的列定义中的default关键字自定。)

create table orderitems

(

order_num                int                       not null,

order_item                int                     not null,

prod_id                       char(10)          not null,

quantity                      int                  not null              default     1,

item_price                 decimal(8,2)     not null,

primary    key (order_num,      order_item)

)ENGINE=InnoDB;

引擎类型

MySQL有一个具体管理和处理数据的内部引擎。

在你使用create table 语句时,该引擎具体创建表,二在你使用select语句或进行其他数据库处理时,该引擎在内部处理你的请求。多说时候,此引擎都隐藏在DBMS内,不需要过多关注他。

InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索;

MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适用于临时表);

MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。

更新表:alter table语句。

为了使用alter table 更改表结构,必须给出下面的信息;

1.在alter table之后给出要更改的表名(该表必须存在,否则将出错 );

2.所做更改的列表。

下面的例子给表添加一个列:

alter   table    vendors

add    vend_phone char(20);

删除刚刚添加的列,可以这样做:

alter    table           vendors

drop    column       vend_phone;

alter  table的一种常见用途是定义外键。

alter   table              orderitems

add    constraint    fk_orderitems_orders

foreign     key (order_num) references orders (order_num);

alter          table         orderitems

add            constraint         fk_orderitems_products          foreign     key   (prod_id)

references        products (prod_id);

alter          table         orders

add            constraint         fk_orders_customers      foreign     key (cust_id)

references        customers (cust_id);

alter          table         products

add            constraint         fk_products_vendors

foreign     key   (vend_id)           references        vendors    (vend_id);

alter          table前应该备份

删除表

drop          table         customers2;

重命名表:rename table;

rename    table customers2   to     customers;

对多个表重命名:

rename    table         backup_customers           to    customers,

backup_vendors                to     vendors,

backup_products              to     products;

22使用视图

视图是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

视图不包含表中应该有的任何列或数据,它包含的是一个SQL查询。

为什么使用视图?
1 重用SQL语句

2 简化复杂的SQL操作

3 使用表的组成部分而不是整个表

4 保护数据

5 更改数据格式和表示。视图可以返回与底层表的表示和格式不同的数据。

在视图创建之后,可以用于表基本相同的方式利用它们。可以对视图执行select,过滤,排序数据,将视图联结到其他视图或表,甚至能添加和更新数据。

重点:视图仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据。因此它们返回的数据是从其他表中检索出来的。在添加或更改这些表中的数据时,视图将返回改变过的数据。

使用视图:

1创建视图create view语句

2使用show create view
viewname;来查看创建视图的语句。

3删除视图,dorp view
viewname;

4更新视图,先drop,再create,也可以直接用create
or replace view;如果要更新的视图不存在,则第二条更新语句会创建一个视图;如果要更新的视图存在,则第二条更新语句会替换原有视图。

create view      productcustomers   AS

select cust_name, cust_contact, prod_id

from customers ,orders , orderitems

where       customers.cust_id
= orders.cust_id

AND          orderitems.order_num
= orders.order_num;

这条语句创建一个名为productcustomers的视图,它联结三个表,返回已订购了任意产品的所有客户的列表。

select * from productcustomers;将列出订购了任意产品的客户。

select cust_name, cust_contack

from productcustomers

where prod_id = ‘TNT2’;

用视图重新格式化检索出的数据

select Concat(RTrim(vend_name), ‘ (),
RTrim(vend_country),’)’)  AS vend_title

from vendors

order by vend_name;

将以上语句转换为视图

create view vendorlocations AS

select Concat(RTrim(vend_name), ‘ (‘,
RTrim(vend_country), ‘) ’ )

AS vend_title

from vendors

order by vend_name;

select * from vendorlocations;

create view customeremaillist AS

select cust_id, cust_name,cust_email

from customers

where cust_email IS NOT NULL;

select * from custmeremaillist;

select prod_id,

quantity,

item_price,

quantity*item_price AS expanded_price

from orderitems

where order_num = 20005;

将其转换为一个视图;

create view orderitemsexpanded AS

select order_num,

prod_id,

quantity,

item_price,

quantity*item_price AS expanded_price

from orderitems;

select * from orderitermsexpanded

where order_num = 2005;

事务处理(transaction
processing)可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。

事务处理时一中机制,用来管理必须成批执行的MySQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组操作不会中途停止,它们或者作为整体执行,或者完全不执行。如果没有错误发生,整组语句提交给数据库表。如果发生错误,则进行回退,

以恢复数据库到某个已知且安全的状态。

事务处理的几个术语:

事务(transaction)值一组SQL语句;

回退(rollback)指撤销指定SQL语句的过程;

提交(commit)指将未存储的SQL语句结果写入数据库表;

保留点(savepoint)指事务处理中设置的临时占位符(place-holder),可以对它发布回退(与回退整个事务处理不同)。

管理事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退。

MySQL标识事务的开始:start
transaction

使用rollback(撤销MySQL语句)

select * from ordertotals;

start transaction;

delete from ordertotals;

select * from ordertotals;

rollback;

select * from ordertotals;

rollback只能在一个事务处理内使用(在执行一条start
transaction命令之后)。

使用commit

一般的MySQL语句都是直接针对数据库表执行和编写的。这就是所谓的隐含提交(implicit commit),即提交(写或保护)操作是自动进行的。

在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用commit语句,如下所示:

start transaction;

delete from orderitems where order_num =
20010;

delete from orders where order_num = 20010;

commit;