SQL必知必会--阅读笔记20210120

本文详细介绍了SQL的SELECT语句,包括数据检索、排序、分组、联结、计算字段、过滤、聚合函数和视图的使用,以及存储过程、游标等高级特性。涵盖了创建视图、更新数据、数据插入、删除操作和数据库管理的全面指南。
摘要由CSDN通过智能技术生成

SELECT语句-检索数据
用途是从一个或多个表中检索信息。
至少给出两条信息–想选择什么,以及从什么地方选择

SELECT prod_name, prod_id, prod_price 
FROM Products; 
#从名为Products的表中,检索一个名为prod_name的列

SELECT * #表示返回表中所有列
SELECT DISTINCT vend_id
FROM Products; #检索出不同的值,避免了重复。DISTINCT必须放在列名的前面,作用于所有的列


1.如果没有明确排序结果,那么返回的数据没有特定的顺序;
2.多条语句必须要用分号隔开;
3.对SQL关键字使用大写,对列名和表名使用小写;
4.所有空格都会被忽略,的按多行更容易阅读和调试;

只返回一定数量的行
!SQL Sever 和Access使用的情况下,用TOP关键字

SELECT TOP 5 prod_name
FROM Procuts;

!DB2使用的情况下

SELECT prod_name
FROM Products
FETCH FIRST 5 ROWS ONLY;

!Oracle使用的情况下

SELECT prod_name
FROM Products
WHERE ROWNUM <=5;

!MySQL、MariaDB、PostgreSQL、SQLite使用的情况下

SELECT prod_name --这是一条注释
/*这也是一条长长的注释
注释guagua*/
FROM Products
LIMIT 5; #返回不超过5行的数据
LIMIT 5 OFFSET 3; #从第5行起的3行数据

ORDER BY子句–排序检索数据

SELECT prod_name
FROM Products;
ORDER BY prod_name; #以字母顺序排序数据
ORDER BY 2,3 #先按SELECT清单中的第三列prod_price排序,再按第二列prod_name进行排序

(ORDER BY语句应该保证是SELECT语句的最后一条子句。)

SELECT prod_id.prod_price,prod_name
FROM Products;
ORDER BY prod_price DESC, prod_name;
*以降序排列产品(最贵的在最前面),再加上产品名

DESC关键字是DESCENDING的缩写,只应用到直接位于其前面的列名。上例中,仅对prod_price列指定DESC,对prod_name不指定。
ASC是ASCENDING的缩写,在升序排序时可以指定。但一般情况下,默认升序。

WHERE子句过滤数据

SELECT prod_name, prod_price
FROM Products
WHERE prod_price=3.49; #只返回prod_price值为3.49的行

(在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后)
在这里插入图片描述

SELECT prod_name, prod_price
FROM Products
WHERE prod_price<10;  #列出所有价格小于10美元的产品

SELECT vend_id, prod_name
FROM Products
WHERE vend_id<>'DLL01'; #列出所有不是供应商DLL01制造的产品
WHERE vend_id !='DLL01'; #同上。但Microsoft Access不支持!=

SELECT prod_name, prod_price
FROM Products
WHERE prod_pric BETWEEN 5 AND 10; #检索价格在5美元和10美元之间的所有产品

SELECT prod_name, prod_price
FROM Products
WHERE prod_pric IS NULL; #用IS NULL子句返回所有没有价格的产品

单引号用来限定字符串;若将值与字符串类型的列进行比较,就需要限定引号

WHERE子句建立高级数据过滤
AND子句

SELECT prod_id, prod_name, prod_price
FROM Products
WHERE vend_id='DLL01' AND prod_price<=4; #返回供应商为DLL01,同时产品价格大于4美元的行

(以上例子中仅包含1个AND子句,因此最多有两个过滤条件。可以增加多个过滤条件,每个条件间都要使用AND关键字)

OR子句

SELECT prod_name, prod_price
FROM Products
WHERE vend_id='DLL01' OR vend_id='BRS01';

OR操作符正好与AND操作符相反。
许多DBMS在OR WHERE子句的第一个条件得到满足的情况下,就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)

SELECT prod_name, prod_price
FROM Products
WHERE (vend_id='DLL01' OR vend_id='BRS01') AND prod_price >=10;
#列出价格为10美元及以上,且由DLL01或BRS01制造的所有产品

(SQL在处理OR操作符之前,会优先处理AND操作符,因此得用圆括号对操作符进行明确分组)

IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配

SELECT prod_name, prod_price
FROM Products
WHERE vend_id IN ('DLL01','BRS01') #检索由供应商DLL01和BRS01制造的所有产品
#等价于vend_id='DLL01' OR vend_id='BRS01'
ORDER BY prod_name;

IN的最大优点是可以包含其他SELECT语句,能够更动态地建立WHERE语句

NOT操作符
有且只有一个功能:否定其后所跟的任何条件。可以用在要过滤的列前,而不仅是在其后。

SELECT prod_name
FROM Products
WHERE NOT vend_id='DLL01' #否定跟在其后的条件
#也可表示为 WHERE vend_id<> 'DLL01'
ORDER BY prod_name;

用LIKE操作符进行通配搜索,进行复杂过滤
通配符:wildcard,用来匹配值的一部分的特殊字符。只能用于文本字段(字符串),非文本数据类型字段不能使用通配符搜索。

百分号%通配符

SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'Fish%'; #找出所有以Fish起头的产品
WHERE prod_name LIKE 'F%y'; #找出以F起头、y结尾的所有产品
WHERE prod_name LIKE '%bean bag%'; #可以使用多个通配符
WHERE email LIKE 'b%@forta.com'; #根据邮件地址的一部分来查找电子邮件


通配符%不能匹配NULL
如果用Microsoft Access, 需要使用*而不是%。
根据DBMS的不同及其配置,搜索可以是区分大小写的。

下划线_通配符
只能匹配单个字符,而不是多个字符
如果使用的是Microsoft Access,而不是 _

方括号[ ]通配符
用来指定一个字符集,必须匹配指定位置的一个字符
只有Microsoft Access和SQL Server支持集合

SELECT cust_contact
FROM Customers
WHERE cust_contact LINK '[JM]%' --找出所有名字以J或M起头的联系人
--[JM]匹配方括号中任意一个字符,仅匹配单个字符,%通配符匹配第一个字符之后的任意数目的字符,返回所需结果
ORDER BY Cust_contact;

该通配符的否定是前缀字符^(脱字号)。

SELECT cust_contact
FROM Customers
WHERE cust_contact LINK '[^JM]%'
--等价于 WHERE NOT cust_contact LIKE '[JM]%'
ORDER BY Cust_contact;

如果使用的是Microsoft Access,需要用!而不是^来否定一个集合。

创建计算字段
字段:field等同于列,但是数据库列一般称为列,而术语字段通常与计算字段一起使用。
计算字段并不实际存在于数据库表中,而是在运行时在SELECT语句内创建的

拼接:concatenate将值联结到一起构成单个值

SELECT vend_name + '('+vend_country+')'--多数情况是这种
SELECT vend_name || '('||vend_country||')'
SELECT vend_name , '(', vend_country, ')'--MySQL和MariaDB中使用的语句
FROM Vendors
ORDER BY vend_name; 

其中Access和SQL Server使用+号;DB2,Oracle,PostgreSQL, SQLite, Open Office Base使用||

SELECT RTRIM(vend_name) + '('+RTRIM(vend_country)+')' --去掉空格们
FROM Vendors
ORDER BY vend_name;

RTRIM()函数去掉值右边的所有空格、LTRIM()函数去掉字符串左边的空格、TRIM()函数去掉字符串左右两边的空格。
在这里插入图片描述
变为
在这里插入图片描述
别名:alias是一个字段或值的替换名,用AS关键字赋予。有别名之后就可以按照名称引用这个列

SELECT RTRIM(vend_name)+ '('+RTRIM(vend_country)+')'
AS vend_title --指示SQL创建一个包含特定计算结果的名为vend_title的计算字段
FROM Vendors
ORDER BY vend_name;

执行算术计算

SELECT prod_id,
       quantity,
       item_price,
       quantity*item_price AS expanded_price #expanded_price列是一个计算字段
--汇总物品的价格(单价乘以订购数量)
FROM OrderItems
WHERE order_num=20008;

SELECT语句省略FROM子句后就是简单地访问和处理表达式

SELECT 3*2;--将返回6
SELECT Trim(' abc ');--将返回abc
SELECT Now();--将返回当前日期和时间

使用函数处理数据
DBMS函数的差异
文本处理函数
UPPER()函数将文本转换为大写

SELECT vend_name, UPPER(vend_name) AS vend_name_upcase
FROM Vendors
ORDER BY vend_name;

常用的文本处理函数
其中SOUNDEX()是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX不是SQL概念,但多数DBMS都提供对SOUNDX的支持。

日期和时间处理函数(差异较大)

WHERE DATEPART(yy,order_date)=2012;--SQL Server版本
WHERE DATEPART('yyyy',order_date)=2012;--Access版本
WHERE DATE_PART('year',order_date)=2012;--PostgreSQL版本
WHERE to_number(to_char(order_date,'YYYY'))=2012;--Oracle版本

汇总数据
聚集函数:aggregate function对某些行运行的函数,计算并返回一个值。

SELECT AVG(prod_price) AS avg_price --用AVG()函数返回Products表中所有产品的平均价格
FROM Products;
WHERE vend_id='DLL01'; #加一行这个表示返回特定供应商所提供产品的平均价格

AVG()函数忽略列值为NULL的行,如果使用DISTINCT参数,那么平均值只考虑各个不同的价格

SELECT AVG(DISTINCT prod_price) AS avg_price
FROM Products
WHERE vend_id='DLL01'

COUNT()函数

SELECT COUNT(*) AS num_cust--不管表列中包含的是空值NULL还是非空值
SELECT COUNT(cust_email) AS num_cust --对特定列中具有值的行进行计数,忽略NULL值 
FROM Customers;

MAX()函数、MIN()函数

SELECT MAX(prod_price) AS max_price
FROM Products;

SUM()函数

SELECT SUM(quantity) AS items_ordered
SELECT SUM(item_price*quantity) AS total_price
FROM OrderItems
WHERE order_num=20005;

组合聚集函数

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;	

分组数据

计算供应商DLL01提供的产品数目

SELECT COUNT(*) AS num_prods
FROM Products
WHERE vend_id='DLL01'

创建分组

SELECT vend_id, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id; --GROUP BY子句指示DBMS按vend_id排序并分组数据
GROUP BY 2,1; --按选择的第二个列分组,再按第一个列分组

过滤分组
WHERE过滤指定的是行,而HAVING过滤的是分组
WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤

SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*)>=2;--过滤COUNT(*)>=2(两个以上订单)的那些分组
SELECT vend_id,COUNT(*) AS num_prods
FROM Products
WHERE prod_price>=4--过滤prod_price至少为4的行
GROUP BY vend_id
HAVING COUNT(*)>=2; --过滤计数为2及以上的分组
--列出具有两个以上产品且其价格大于等于4的供应商
```1
分组和排序
![ORDER BYGROUP BY的区分](https://img-blog.csdnimg.cn/20210119140048227.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzQ4MjI1NjQ4,size_16,color_FFFFFF,t_70)
**使用子查询**
子查询:subquery,嵌套在其他查询中的查询。

利用子查询进行过滤
例子:列出订购物品RGAN01的所有顾客
(1)检索包含物品RGAN01的所有订单的编号
(2)检索具有前一步骤列出的订单编号的所有顾客的ID
(3)检索前一步骤返回的所有顾客ID的顾客信息

```sql
SELECT order_num
FROM OrderItems
WHERE prod_id='RGAN01';--列出两个包含RGAN01的订单
>>>order_num
>>>20007
>>>20008
SELECT cust_id
FROM Orders
WHERE order_num IN (20007,20008);--查询与订单20007和20008相关的顾客ID
>>>cust_id
>>>1000000004
>>>1000000005

以上两个查询,可以把第一个查询变为子查询

SELECT cust_id
FROM Orders
WHERE order_num IN (SELECT order_num
					FROM OrderItems
					WHERE prod_id='RGAN01');
>>>cust_id
>>>1000000004
>>>1000000005

最后一步是检索这些顾客ID的 顾客信息

SELECT cust_num, cust_contact
FROM Customers
WHERE cust_id IN ('1000000004','1000000005')

可以把WHERE子句转换为子查询

SELECT cust_num, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
				  FROM Orders
			      WHERE order_num IN (SELECT order_num
									  FROM OrderItems
									  WHERE prod_id='RGAN01'));

作为子查询的SELECT语句只能查询单个列

作为计算字段使用子查询
例子:显示Customers表中每个顾客的订单数
步骤如下:
(1)从Customers表中检索顾客列表;
(2)对于检索出的每个顾客,统计其在Orders表中的订单数目

SELECT cust_name,
	   cust_state,
	   (SELECT COUNT(*)--对每个顾客执行
	   FROM Orders
	   WHERE Orders.cust_id= Customers.cust_id) AS orders
	   --比较Orders表中的cust_id和当前正从Customers表中检索的cust_id
FROM Customers
ORDER BY cust_name;

Orders.cust_id= Customers.cust_id用的是完全限定列名,制定表名和列名

联结表
如果数据存储在多个表中,用联结可以在使用一条SELECT语句的情况下就检索出数据。

用SELECT创建联结

SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id=Prodcts.vend_id;
>>>vend_name   prod_name   prod_price
>>>.....

用WHERE建立联结关系。WHERE子句将作为过滤条件,只包含那些匹配给定条件的行。没有WHERE子句,第一个表中的每一行疆域第二个表中的每一行配对,而不管它们逻辑上是否能配在一起。

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

内联结
等值联结,基于两个表之间的相等测试。

SELECT vend_name, prod-name, prod_price
FROM Vendors INNER JOIN Products
 ON Vendors.vend_id= Products.vend_id; 

注意联结条件要用特定的ON子句,而不是WHERE子句。

联结多个表
例子:显示订单20007中的物品

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=20007;--过滤产品
SELECT cust_num, cust_contact
FROM Customers
WHERE cust_id IN (SELECT cust_id
				  FROM Orders
			      WHERE order_num IN (SELECT order_num
									  FROM OrderItems
									  WHERE prod_id='RGAN01'))
用联结来表示:
SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id=Orders.cust_id--关联联结中的表
 AND OrderItems.order_num=Orers.order_num--关联联结中的表
 AND prod_id='RGAN01';--过滤产品

创建高级联结
给列起别名:缩短SQL语句;允许在一条SELECT语句中多次使用相同的表

SELECT RTRIM(vend_name) + '('+ RTRIM(vend_country) + ')'
	   AS vend_title
FROM Vendors
ORDER BY vend_name;

SELECT cust_name, cust_contact
FROM Customers AS C, Orsders AS O, OrderItems AS OI
WHERE C.cust_id=O.cust_id
 AND OI.order_num=O.order_num
 AND prod_id='RGAN01';

联结的类型:自联结(self-join)、自然联结(natural join)、外联结(outer join)
例子:给与Jim Jones同一公司的所有顾客发送信件

用SELECT做子查询

SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name=(SELECT cust_name
 				 FROM Customers
 				 WHERE cust_contact = 'Jim Jones');

使用联结

SELECT c1.cust_id,c1.cust_name,c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name=c2.cust_name
 AND c2.cust_contact='Jim Jones';

自然联结要求只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT*),而对其他表的列使用明确的子集来完成。

SELECT C.*, O.order_num, O.order_data,
	   OI.prod_id, OI.quantities, OI.item_price
FROM Customers AS C, Order AS O, OrderItems AS OI
WHERE C.cust_id=O.cust_id
 AND OI.order_num=O.order_num
 AND prod_id='RGAN01';

外联结:联结包含了那些在相关表中没有关联行的行。
用SELECT检索所有顾客及订单,用内联结

SELECT Customers.cust_id, Orders.order_num
FROM Customers INNER JOIN Orders
 ON Customers.cust-id = Orders.cust_id;

用外联结语法检索包括没有订单顾客在内的所有顾客

SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders --用OUTER JOIN指定联结类型
 ON Customers.cust_id= Orders.cust_id;

使用OUTER JOIN时,必须使用RIGHT/ LEFT关键字指定包括其所有行的表。(RIGHT指 OUTER JOIN右边的表;LEFT指左边的表)

全外联结:full outer join检索两个表中的所有行并关联那些可以关联的行。

SELECT Customers.cust_id, Orders.order_num
FROM Orders FULL OUTER JOIN Customers
 ON Orders.cust_id = Customers.cust_id;

*Access, MariaDB, MySQL, Open Office Base 和 SQLite不支持FULL OUTER JOIN语法。

使用带聚集函数的联结
例子:检索所有顾客及每个顾客所下的订单数

SELECT Customers.cust_id
	   COUNT(Orders.order_num) AS num_ord--对每个顾客的订单计数,作为num_ord返回
FROM Customers INNER JOIN Orders--将Customers 和 Orders 表互相关联
 ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;

聚集函数与其他联结一起使用
例子:使用左外部联结来包含所有顾客,甚至包括那些没有任何订单的顾客

SELECT Customer.cust_id,
	   COUNT(Orders.order_num) AS num_ord
FROM Customers LEFT OUTER JOIN Orders
 ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;

组合查询
SQL允许执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回。
两种情况需要使用组合查询:
1.在一个查询中从不同的表返回结构数据;
2.对一个表执行多个查询,按一个查询返回数据。

创建组合查询
使用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将结果组合成一个结果集。

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI');  --把Illinois, Indiana, Michigan等州的缩写传递给IN字句,检索出这些州的所有行


SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name='Fun4ALL'; --利用简单的相等测试找出所有Fun4All

组合以上两条语句:
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION  ---会取消重复的行
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name='Fun4ALL';
--由前面的两条SELECT语句组成,之间用UNION关键字分隔。UNION指示DBMS执行这两条SELECT语句,并把输出组合成一个查询结果集。

用WHERE子句进行相同的查询如下:

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
 OR cust_name = 'Fun4All'

UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔;
UNION中的每个查询必须包含相同的列、表达式或聚集函数
UNION从查询结果集中自动去除重复的行

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION ALL ---使用UNION ALL,不取消重复的行
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name='Fun4ALL';

对组合查询结果排序
在用UNION组合查询时,只能使用一条ORDER BY子句,必须位于最后一条SELECT语句之后。

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name='Fun4ALL'
ORDER BY cust_name,cust_contact;

插入数据
插入的几种方式:插入完整的行;行的一部分;某些查询的结果

INSERT INTO Customers
VALUES('1000000006',
       'Toy Land',
       '123 Any Street',
       'New York',
       'NY',
       '11111',
       'USA',
       NULL,
       NULL);

等同于:
INSERT INTO Customers(cust_id,
					  cust_name,
					  cust_address,
					  cust_city,
					  cust_state,
					  cust_zip,
					  cust_country,
					  cust_contact,
					  cust_email)
VALUES('1000000006',
       'Toy Land',
       '123 Any Street',
       'New York',
       'NY',
       '11111',
       'USA',
       NULL,
       NULL);
--可以按照不同的次序填充

如果某列没有值,应该使用NULL值;各列必须以他们在表定义中出现的次序填充。

插入检索出的数据–INSERT SELECT
INSERT除了可以用来给表插入具有指定列值的行,还可以将SELECT语句的结果插入表中。
例子:从一个名为CustNew的表中读出数据并插入到Customer表。

INSERT INTO Customers(cust_id,
					  cust_name,
					  cust_address,
					  cust_city,
					  cust_state,
					  cust_zip,
					  cust_country)
SELECT cust_id,
	   cust_name,
	   cust_address,
	   cust_city,
	   cust_state,
	   cust_zip,
	   cust_country
FROM CustNew

INSERT通常只插入一行。如果要插入多行,必须执行多个INSER语句。INSERT SELECT是个例外,可以用一条INSERT插入多行。

从一个表复制到另一个表–SELECT INTO语句
例子:

SELECT * --将在CustCopy表中创建(并填充)与Customers表的每一列相同的列;只复制部分的列,明确列明即可
INTO CustCopy 
FROM Customers; --创建一个名为CustCopy的新表,并把Customers表的整个内容复制到新表中

更新和删除数据
可以用UPDATE更新表中的特定行,所有行。但要保证自己有足够的安全权限
例子:更新客户1000000005的电子邮件地址

UPDATE Customers  --要更新的表
SET cust_contact = 'Sam Roberts', --(更新多个列时,只需要使用一条SET命令)
	cust_email = 'kim@thetoystore.com'  --列名和它们的新值
WHERE cust_id = '1000000005'; --WHERE子句告诉DBMS更新哪一行;如果没有WHERE子句,将会更新Customers表中的所有行

用NULL来删除cust_email列中的值

UPDATE Customers
SET cust_email = NULL --弱国是空字符串,用' '表示
WHERE cust_id = '1000000005';

删除特定的行(不是删除列,删列的话用UPDATE语句)

DELET FROM Customers --要求指定从中删除数据的表名
WHERE cust_id='1000000006';  --WHERE子句过滤要删除的行;如果省略WHERE子句,将删除表中每个顾客

创建和操纵表
两种创建表的方法:1.运用DBMS的交互式创建和管理数据库表的工具 2.直接用SQL语句操纵–CREATE TABLE

CREATE TABLE Products --新表的名字,在CREATE TABLE之后给出
(
	prod_id   CHAR(10)        NOT NULL,--表列要么是NULL列,要么是NOT NULL列
	vend_id   CHAR(10)        NOT NULL,
	prod_name  CHAR(10)       NOT NULL    DEFAULT dear, --如果不给出名字则使用dear来代替
	prod_price DECIMAL(8,2)   NOT NULL,
	prod_desc  VARCHAR(1000)  NULL
); --给出表列的名字和定义,用逗号分隔

更新表

ALTER TABLE Vendors --在ALTER TABLE之后给出要更改的表名(必须存在)
ADD vend_phone CHAR(20); --列出要做哪些更改 (增加一个名为vend_phone的列,数据类型为CHAR)
DROP COLUMN vend_phone;--删除名为vend_phone的列

删除表

DROP TABLE CustCopy; --直接用DROP TABLE语句删除整个表即可

使用视图
视图只包含使用时动态检索数据的查询
创建视图

CREATE VIEW ProductCustomers AS --创建一个名为ProductCustomers的视图
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;

从视图中检索产品

SELECT cust_name,cust_contact
FROM ProductCustomers
WHERE prod_id= 'RGAN01'; --检索订购了产品RGAN01的顾客

视图的另一用途:重新格式化检索出的数据

用SELECT语句在单个组合计算列中返回供应商名和位置

SELECT RTRIM(vend_name) + '('+ RTRIM(vend_country) + ') '
	   AS vend_title
FROM Vendors
ORDER BY vend_name;

创建一个视图,使用它即可。

CREATE VIEW VendorLocations AS
SELECT RTRIM(vend_name) + '( '+ RTRIM (vend_country) +')'
	   AS vend_title
FROM Vendors;

用视图过滤不想要的数据
例子:定义CustomerEMailList视图,过滤没有电子邮件地址的顾客

CREATE VIEW CustomerEMailList AS
SELECT cust_id, cust_name, cust_email
FROM Customers
WHERE cust_email IS NOT NULL;

使用视图与计算字段
用SELECT语句检索某个订单中的物品,计算每种物品的总价格

SELECT prod_id,
	   quantity, 
	   item_price,
	   quantity*item_price AS expanded_price
FROM OrderItems
WHERE order_num = 20008;

将上述转换为一个视图:

CREATE VIEW OrderItemsExpanded AS
SELECT order_num,
	   prod_id,
	   quantity,
	   item_price,
	   quantity*item_price AS expanded_price
FROM OrderItems;
UNION 
SELECT *
FROM OrderItemsExpanded
WHERE order_num = 20008;

【以下开始晕乎乎—】
使用存储过程
存储过程:为以后使用而保存的一条或多条SQL语句。可将其视为批文件,虽然他们的作用不仅限于批处理。

执行存储过程
例子:执行一个名为AddNewProduct的存储过程,将一个新产品添加到Products表中。

EXECUTE AddNewProduct ('JTS01',
					   'Stuffed Eiffel Tower',
					   6.49,
					   'Plush stuffed toy with the text LaTour Eiffel in red white and blue');

创建存储过程
例子:对邮件发送清单中具有邮件地址的顾客进行技术。(Oracle版本)

CREATE PROCEDURE MailingListCount(
  ListCount OUT INTEGER 
 )
 IS
 v_rows INTEGER;
 BEGIN
 	  SELECT COUNT(^) INTO c_rows
 	  FROM Customers
 	  WHERE NOT cust_email IS NULL;
 	  ListCount := v_rows;
END;

解析:
使用游标
DECLARE命名游标。创建一个游标来检索没有电子邮件地址的所有顾客,作为应用程序的组成部分,帮助操作人员找出孔雀的电子邮件地址。

DECLARE CustCursor CURSOR
FOR 
SELECT * FROM Customers
WHERE cust_email IS NULL --DB2,MariaDB, MySQL, SQL Server版本

OPEND CURSOR CustCursor--打开游标
CLOSE CustCursor--关闭游标


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值