SQL必会必知


title: SQL必会必知
tag: 标签名
categories: 分类
comment: 是否允许评论(true or false)
description: 描述
top_img: https://z3.ax1x.com/2021/10/06/4xq2s1.png

cover: https://z3.ax1x.com/2021/10/06/4xq2s1.png

了解SQL

数据库基础

什么是数据库

数据库是一个以某种有组织的方式存储的数据集合。一个简单的方法就是将其想象为一个文件柜。

数据库保存有组织的数据的容器(通常是一个文件或一组文件)

在将资料放入文件柜中,不是随便将它们扔进某个抽屉中,而是在文件柜中创建文件,然后将相关的资料放入特定的文件中。

表是一种结构化的文件,可用来存储某种特定类型的数据。

某种特定类型数据的结构化清单。

数据库中的每个表都有一个用来标识自己的名字。此名字是唯一的,这表示数据库中没有其他表具有相同的名字。

列数数据类型

表由列组成。列中存储着表中某部分的信息。

表中的一个字段。所有表都是由一个或多个列组成的。

理解列的最好办法是将数据库想象为一个网格。网格中每一列存储着一条特定的信息。

**数据类型:**所容许的数据的类型。每个表列都有相应的数据类型,它限制该列中存储的数据。

表中的数据是按行存储的;所保存的每个记录存储在自己的行内。

**行:**表中的一个记录。

主键

一列,其值能够唯一标识表中每个行。

表中的任何列都可以作为主键,只要它满足以下条件:

  • 任意两行都不具有相同的主键值
  • 每个行都必须具有一个主键值(主键值不允许为NULL值)
  • 主键列中的值不允许修改或更新
  • 主键值不能重用

什么是SQL

SQL是结构化查询语言(Structured Query Language)的缩写。

SQL有如下的优点:

  • SQL不是某个特定数据库供应商专有的语言。
  • SQL简单易学。它的语句全都是有很强描述性的英语单词组成,而且这些单词的数目不多。
  • SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活使用其他语言元素,可以进行非常复杂和高级的数据库操作。

SELECT语句

它的用途是从一个或多个表中检索信息。

关键字:作为SQL组成部分的保留字。关键字不能用作表或列的字。

检索单个列

select prod_name from  Products;

分析:从Products表中检索一个名为prod_name的列。所需的列在select关键字之后给出。

输出结果:

HmentP.png

上面的一条语句将返回表中的所有行。这里的数据没有经过过滤。

  • 使用空格:在处理SQL语句时,其中所有的空格都会被忽略。

  • 结束SQL语句:多条SQL语句必须以分号结尾;

  • SQL语句和大小写:SQL语句不区分大小写。

检索多个列

想从一个表中检索多个列,使用相同的select语句。唯一不同的是必须在select关键字后给出多个列名,并且列名之间用逗号分割。

输入:

select prod_id,prod_name,prod_price from Products;

输出:

Hme0cF.png

检索所有列

使用通配符*来达到。

输入:

SELECT * from Products;

输出:

Hmef1O.png

排序检索数据

排序数据

为了明确地排序用select语句检索出的数据,可使用order by子句。order by子句取一个或多个列的名字。

输入:

select prod_name FROM Products ORDER BY prod_name;

输出:

Hmmi40.png

ORDER BY 子句的位置:在指定一条order by子句时,应保证它是select语句中最后一条语句。

按多个列排序

输入:

select prod_id,prod_price,prod_name FROM Products ORDER BY prod_price,prod_name;

输出:

HmnPqH.png

排序的顺序完全按照所规定的进行。对于上面的例子,仅在多个行具有相同的prod_price值时才对产品按prod_name进行排序。

按列位置排序

输入:

select prod_id,prod_price,prod_name from Products ORDER BY 2,3;

输出:

Hmn0eJ.png

select清单中的第二个列,prod_prcie列进行排序,order by 2,3表示先按prod_price,再按prod_name进行排序。

指定排序方向

升序排序(从A到Z)。这是默认的排序顺序,还可以使用ORDER BY子句进行降序排序(从Z到A)顺序排序。为了进行降序排序,必须使用指定DESC关键字。

输入:

select prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC;

输出:

HmuMp6.png

如果对多个列排序怎么办?

输入:

select prod_id,prod_price,prod_name FROM Products ORDER BY prod_price DESC,prod_name;

输出:

HmKpHH.png

DESC关键字只应用到直接位于其前面的列名。在上述例子中,prod_price指定以DESC进行排序,对prod_name列不指定。因此,prod_price列以降序进行排序,而prod_name列仍然按标准的升序排序。

过滤数据

使用where子句

只检索所需数据需要指定搜索条件,搜索条件也称为过滤条件。

在select语句中,数据根据where子句中指定的搜索条件进行过滤。where子句在表名之后给出。

输入:

select prod_id,prod_name,prod_price from Products WHERE prod_price = 3.49;

输出:

HmMkdJ.png

WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后,否则将会产生错误。

where子句操作符

操作符说明
=等于
<>不等于
!=不等于
<小于
<=小于等于
!<不小于
>大于
>=大于等于
!>不大于
BETWEEN在指定的两个值之间
IS NULL为NULL值

检查单个值

输入:

select prod_name,prod_price FROM Products WHERE prod_price < 10;

输出:

HmQSkd.png

不匹配检查

输入:

select vend_id,prod_name FROM Products WHERE vend_id != 'DLL01';

输出:

HmQzuT.png

范围值检查

为了检查某个范围的值,可使用BETWEEN操作符。

输入:

SELECT prod_name,prod_price FROM Products  WHERE prod_price BETWEEN 5 AND 10;

输出:

HmlnbD.png

从上面这个例子可以看出,在使用between时,必须指定两个值–所需范围的低端和高端值。

空值检查

输入:

SELECT vend_id FROM Vendors where vend_state is NULL;

输出:

Hm1GFJ.png

高级数据过滤

组合WHERE子句

AND操作符

输入:

SELECT prod_id,prod_price,prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price <= 4;

输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eR3LQXef-1644392414458)(C:\Users\QJS\AppData\Roaming\Typora\typora-user-images\image-20220205123833164.png)]

检索出由供应商DLL01制造且价格小于等于4美元的俩个条件。

AND:用在WHERE子句中的关键字,用来指示检索满足所有给定条件的行。

OR操作符

输入:

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

输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XT4dX6xp-1644392414459)(C:\Users\QJS\AppData\Roaming\Typora\typora-user-images\image-20220205124344449.png)]

**OR:**WHERE子句中使用的关键字,用来表示检索匹配任一给定条件的行。

计算次序

WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂和高级的过滤。

输入:

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

输出:

HmaulQ.png

**注意:**上述的结果中可以看到输出的价格有的小于10美元,为什么会出现现在这样的状况,SQL在处理OR操作符之前,优先处理AND操作符。当SQL看到上述WHERE语句后,它理解为由供应商BRS01制造的任何价格10美元以上的产品,或者由供应商DLL01制造的任何产品,而不管价格如何。如果想要修改,如下:

输入:

SELECT prod_name,prod_price FROM Products WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01')AND prod_price >= 10 ;

输出:

Hmdi3F.png

分析:这条SQL语句和上面的语句相比,这条语句中,前两个语句由括号括起来,圆括号的计算次序比AND和OR的计算优先级别高。

IN操作符

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

输入:

SELECT prod_name,prod_price FROM Products WHERE vend_id IN('DLL01','BRS01') ORDER BY prod_name;

输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sTRLHbrX-1644392414460)(C:\Users\QJS\AppData\Roaming\Typora\typora-user-images\image-20220205133701084.png)]

分析:此SELECT语句检索供应商DLL01和BRS01制造的所有产品。IN操作符后跟由逗号分割的合法值清单,整个清单必须括在圆括号中。

IN操作符和OR操作符的功能差不多。

NOT操作符

where子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。因为NOT从不自己使用,它的语法与其他操作符有所不同,NOT可以用在要过滤的列前,而不仅是在其后。

NOT WHERE子句中用来否定后跟条件的关键字。

输入:

SELECT prod_name FROM Products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name;

输出:

HmgBFJ.png

用通配符进行过滤

LIKE操作符

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

通配符搜索只能用于文本字段(串),非文本数据类型字段不能使用通配符搜索。

百分号(%)通配符

在搜索串中,%表示任何字符出现任意次数。

输入:

SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE 'Fish%';

输出:

HmRl2n.png

分析:此例子中使用搜索模式’Fish%’。在执行这条子句时,将检索任意以Fish起头的词。%告诉DBMS接受Fish之后的任意字符。

输入:

SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE '%bean bag%';

输出:

HmRrKx.png

分析:搜索模式’%bean bag%'表示匹配任何位置包含文本bean bag的值,而不论它之前或之后出现什么字符。

下划线(_)通配符

下划线的用途和%一样,但下划线只匹配单个字符而不是多个字符。

输入:

SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE '__ inch teddy bear';

输出:

HmWdw8.png

分析:上面的下划线为两个通配符。所以匹配的为12和18

%可以匹配0和多个,但是_总是只能匹配一个字符,不能多也不能少。

方括号([])通配符(MYSQL不支持)

方括号通配符用来指定一个字符集,它必须匹配指定位置的一个字符。

例如,为找出所有名字以J或M起头的联系人,如下:

使用统配符的技巧

通配符的功能很好用,但是这种功能是有代价的,如:通配符搜索的处理一般要比前面讨论的其他搜索所花时间更长,这里给出一些使用通配符要记住的技巧:

  • 不要过分使用通配符。如果其他操作能够达到相同的目的,应该使用其他操作符。
  • 在确实需要使用通配符,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
  • 仔细注意通配符的位置。如果犯错地方,可能不会返回想要的数据。

使用数据处理函数

文本处理函数

使用RTRIM()函数来去除列值右边的空格。这次使用UPPER()函数

输入:

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

输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzZwbUMx-1644392414462)(C:\Users\QJS\AppData\Roaming\Typora\typora-user-images\image-20220205161707538.png)]

UPPER()将文本转换为大写,因此转换的结果出现俩次。

常用的文本处理函数:

Hm7wGT.png

日期和时间处理函数

输入:

SELECT order_num FROM Orders WHERE YEAR(order_date) = 2004;

输出:

HuMEJs.png

数值处理函数

常见数值处理函数

函数说明
ABS()返回一个数的绝对值
COS()返回一个角度的余弦
EXP()返回一个数的指数值
PI()返回圆周率
SIN()返回一个角度的正弦
SQRT()返回一个数的平方根
TAN()返回一个角度的正切

汇总数据

聚集函数

聚集函数:运行在行组上,计算和返回单个值的函数。

​ SQL聚集函数

函数说明
AVG()返回某列的平均值
COUNT()返回某列的行数
MAX()返回某列的最大值
MIN()返回某列的最小值
SUM()返回某列值之和
AVG()函数

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

使用AVG()返回Products表中所有产品的平均价格:

输入:

SELECT AVG(prod_price) AS avg_price FROM Products;

输出:

HuluaF.png

分析:SELECT语句返回值avg_price,它包含Products表中所有产品的平均价格。

AVG()也可以用来确定特定列或行的平均值。

输入:

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

输出:

HulBRA.png

只用于单个列 AVG()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出,为了获得多个列的平均值,必须使用多个AVG()函数。

NULL值 AVG()函数忽略列值为NULL行

COUNT()函数

利用COUNT()确定表中行的数目或符合特定条件的行的数目。

count()函数有两种使用方式:

  • 使用COUNT(*)对表中行的数目进行计数,不管表列种包含的是空值(NULL)还是非空值。
  • 使用COUNT(column)对特定列中具有值得行进行计数,忽略NULL值。

输入:

SELECT COUNT(*) AS num_cust FROM Customers;

输出:

Hu1tln.png

分析:利用COUNT(*)对所有行计数,不管行中各列有什么值。计数值在num_cust中返回。

输入:

SELECT COUNT(cust_email) AS num_cust FROM Customers;

输出:

Hu3eNF.png

MAX()函数

输入:

SELECT MAX(prod_price) AS max_price FROM Products;

输出:

Hu3t4e.png

MIN()函数

输入:

SELECT MIN(prod_price) AS min_price FROM Products;

输出:

Hu32CQ.png

分析:其中MIN()返回Products表中最便宜物品的价格。

SUM()函数

SUM()用来返回指定列值的和(总计)。

输入:

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

输出:

Hu8k2d.png

分析:函数SUM(quantity)返回订单中所有物品数量之和,WHERE子句保证只统计某个物品订单中的物品。

聚集不同值

以上5个聚集函数都可以如下使用:

  • 对所有的行执行计算,指定ALL参数或不给参数。
  • 只包含不同的值,指定DISTINCT参数。

输入:

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

输出:

Hu8jJg.png

分析:DISTINCT表示考虑平均值只考虑不同的价格。

注意: 指定列名,则DISTINCT只能用于COUNT(),DISTINCT不能用于COUNT(*)。DISTINCT必须使用列名,不能用于计算或表达式。

组合聚集函数

输入:

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;

输出:

HuGN6A.png

分组数据

创建分组

输入:

select vend_id,count(*) AS num_prods FROM Products GROUP BY vend_id;

输出:

HujU0O.png

分析:上面的SELECT语句指定了两个列,vend_id包含产品供应商的ID,num_prods为计算字段。GROUP BY子句指示DBMS按vend_id排序并分组数据。这导致对每个vend_id而不是整个表计算num_prods一次。

使用了GROUP BY,就不必要指定要计算和估值的每个组。系统会自动完成。GROUP BY子句指示DBMS分组数据,然后对每个组而不是整个结果进行聚集。

在具体使用GROUP BY子句前,需要知道一些重要的规定:

  • GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。
  • 如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。
  • 大多数SQL实现不允许GROUP BY列带有长度可变的数据类型
  • 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。
  • 如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL值,它们将分为一组。
  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

过滤分组

除了能用GROUP BY分组数据外,SQL还允许过滤分组,规定包括哪些分组,排序哪些分组。

如果想要列出至少有两个订单的所有顾客。

HAVING子句和WHERE非常类似,可以说目前所学的所有类型WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。

输入:

SELECT cust_id,COUNT(*) AS orders FROM Orders GROUP BY cust_id HAVING COUNT(*) >= 2;

输出:

HKF8at.png

分析:这条SELECT语句的前面类似于上面的语句。最后一行增加了HAVING子句,它过滤COUNT(*)>=2的那些分组。

HAVING和WHERE的差别, WHERE在数据分组前进行过滤,HAVING在数组分组后进行过滤。

输入:

SELECT vend_id,COUNT(*) AS num_prods FROM Products WHERE prod_price >= 4 GROUP BY vend_id HAVING COUNT(*) >= 2;

输出:

HKAG38.png

分析:这条语句中,使用了聚集函数的基本SELECT,WHERE子句过滤所有prod_price至少为4的行。然后按vend_id分组数据,HAVING子句过滤计数为2或2以上的分组。

分组和排序

虽然GROUP BY和ORDER BY经常完成相同的工作,但它们是非常不同的。

HKE7iq.png

检索包含3个或3个以上物品的订单号和订购物品的数目。

输入:

SELECT order_num,COUNT(*) AS items FROM OrderItems GROUP BY order_num HAVING COUNT(*) >= 3;

输出:

HKVJmQ.png

为按订购物品的数目排序输出,需要添加ORDER BY子句,如下所示:

输入:

SELECT order_num,COUNT(*) AS items FROM OrderItems GROUP BY order_num
HAVING COUNT(*) >= 3 ORDER BY items,order_num;

输出:

HKV56O.png

SELECT子句排序

​ select子句及其顺序

HKVLtI.png

使用子查询

子查询

查询:任何SQL语句都是查询。

SQL还允许创建子查询,即:嵌套在其他查询中的查询。

利用子查询进行过滤

假如需要列出订购物品RGAN01的所有客户,应该怎样检索:

  • 检索包含物品GGAN01的所有订单编号
  • 检索具有前一步骤列出的订单编号的所有客户的ID
  • 检索前一步骤返回的所有客户ID的客户信息

以上的每个步骤都可以单独作为一个查询来执行。可以把一条SELECT语句返回的结果用于另一条SELECT语句的WHERE子句。

首先,对于prod_id为RGAN01的所有订单物品,它检索其order_num列。输出列出两个包含此物品的订单。

输入:

SELECT order_num FROM OrderItems WHERE prod_id = 'RGAN01';

输出:

HM1R00.png

下一步,查询具有订单20007和20008的客户ID。

输入:

SELECT cust_id FROM Orders WHERE order_num IN (20007,20008);

输出:

HM1L0x.png

现在将第一个查询变为子查询组合两个查询。

输入:

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

输出:

HM38EV.png

分析:在SELECT语句中,子查询总是从内向外处理。

作为计算字段使用子查询

假设需要显示Customers表中每个客户的订单总数。订单与相应的客户ID存储在Orders表中。

为了执行上述的步骤,遵循下面的步骤:

  • 从Customers表中检索客户列表。
  • 对于检索出的每个客户,统计其在Orders表中的订单数目。

输入:

SELECT cust_name,cust_state, 
(SELECT count(*) FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS Orders 
FROM Customers ORDER BY cust_name;

输出:

HMGR0I.png

分析:这条SELECT语句对Customers表中每个客户返回3列:cust_name,cust_state,Orders。Orders是一个计算字段,它是由圆括号中的子查询建立。该子查询对检索出的每个客户执行一次。在此例子中,该子查询执行了5次,因为检索出5个客户。

子查询中的WHERE子句与之前使用的稍有不同,因为它使用了完全限定列名。它告诉SQL比较Orders表中的cust_id与当前从Customers表中检索的cust_id;

WHERE Orders.cust_id = Customers.cust_id

联结表

联结

SQL最强大的额功能之一就是能在数据查询的执行中联结(join)表。联结是利用SQL的SELCT能执行的最重要的操作。

关系表

假如有一个包含产品目录的数据库表,其中每种类别的物品占一行,对于每种物品要存储的信息包括产品描述和价格,以及生产该产品的供应商信息。

现在,假如有由同一个供应商生产的多种物品,那么在何处存储供应商信息呢?将这些数据与产品信息分开存储的理由如下:

  • 因为同一供应商生产的每个产品的供应商信息都是相同的,对每个产品重复此信息既浪费时间有浪费存储空间。
  • 如果供应商信息改变,只需改动一次即可。
  • 如果有重复数据,很难保证每次输入该数据的方式都相同。不一致的数据在报表中很难利用。

关键是,相同数据出现多次决不是一件好事,此因素是关系数据库设计的基础。关系表的设计就是保证把信息分解成多个表,一类数据一个表。各表通过某些常用的值互相关联。

在上面的例子中可以建立两个表,一个存储供应商信息,另一个存储产品信息。

Vendors表包含所有供应商信息,每个供应商占一行,每个供应商具有唯一的标识。此标识称为主键,可以是供应商ID或任何其他唯一值。

Products表只存储产品信息,它除了存储供应商ID(Vendors表的主键)外不存储其他供应商信息。Vendors表的主键将Vendors表与Products表关联,利用供应商ID能从Vendors表中找出相应供应商的详细信息。

这样做的好处:

  • 供应商信息不重复,从而不浪费时间和空间
  • 如果供应商信息变动,可以只更新Vendors表中的当个记录,相关表中的数据不用改动。
  • 由于数据无重复,显然数据是一致的,这使得处理数据更简单。

为什么要使用联结

分解数据为多个表能更有效地存储,更方便地处理,并且具有更大的可伸缩性。

如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?

答案是使用联结。简单地说,联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。

创建联结

输入:

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

输出:

HMdmCt.png

分析:select语句与前面所有语句一样指定要检索的列。这里,最大的差别是所指定的两个列(prod_name和prod_price)在一个表中,而另一个列(vend_name)在另一个表中。

接下来看FROM语句,与之前的FROM语句不一样,这条语句的FROM子句列出了两个表,分别是:Vendors和Products。它们就是这条SELECT语句联结的两个表的名字。这两个表用WHERE子句正确联结,WHERE子句指示DBMS匹配Vendors表中的Vend_id和Products表中的vend_id.

可以看到要匹配的两个列以Vendors.vend_id , Products.vend_id指定。这里需要这种完全限定列名,因为如果只给出vend_id,则DBMS不知道指的是哪一个。

WHERE子句的重要性

在联结两个表时,你实际上做的时将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,它只包含那些匹配给定条件的行。没有WHERE子句,第一表中的每个行将与第二个表中的每个行配对,而不管它们逻辑上是否可以配在一起。

输入:

SELECT vend_name,prod_name,prod_price FROM Vendors,Products ;

输出:

HM6RDP.png

分析:从上面的输出中可以看出,相应的笛卡尔积不是我们想要的。

内部联结

基于两个表之间的相等测试。这种联结也称为内部联结。对于这种联结可以使用稍微不同的语法来明确联结的类型。

输入:

SELECT vend_name,prod_name,prod_price FROM Vendors INNER JOIN Products ON Vendors.vend_id = Products.vend_id;

输出:

HMc0rq.png

联结多个表

SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系。如:

输入:

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;

输出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HOUYpr3N-1644392414474)(C:\Users\QJS\AppData\Roaming\Typora\typora-user-images\image-20220207133836242.png)]

分析:显示编号为20007的订单中的物品。订单物品存储在OrderItems表中。每个产品按其产品ID存储,它引用Products表中的产品。这些产品通过供应商ID联结到Vendors表中相应的供应商,供应商ID存储在每个产品的记录中。

性能考虑:这种处理可能时非常耗费资源的,因此应该仔细,不要联结不必要的表,联结的表越多,性能下降越厉害。

创建高级联结

使用表别名

输入:

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 = 'RGAN01';

输出:

HMWmwt.png

分析:表的别名不仅能用于WHERE语句中,还可以运用于ORDER BY子句以及语句的其他部分。

Oracle 中没有AS Oracle不支持AS关键字,为在Oracle中使用别名,可以不用AS,简单地指定列名即可。如(Customers C 而不是Customers AS C)

使用不同类型的联结

自联结

假如想发送一封信件给Jim Jones所在的公司的所有客户。此查询要求首先找出Jim Jones工作的公司,然后找出为此公司工作的客户。

输入:

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

输出:

HMhSPK.png

分析:这是一种简单的解决办法,使用了子查询。内部的SELECT语句做了一个简单的检索,返回Jim Jones工作的公司的cust_name.

该名字用于外部查询的WHERE子句中,以便检索出为该公司工作的所有雇员。

也可以使用连接的相同的查询:

输入:

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';

输出:

HM4wff.png

外部联结

许多联结将一个表中的行与另一个表中的行相关联。但有时候会需要包含没有关联行的那些行。例如,可能需要使用联结来完成以下工作。

  • 对每个客户下了多少单进行计数,包括那些没有人订购的产品
  • 列出所有产品以及订购数量,包括没有人订购的产品
  • 计算平均销售规模,包括那些至今尚未下订单的客户。

联结包含了那些在相关表中没有关联行的行,这种类型的联结称为外部联结。

输入:为了检索所有客户,包括那些没有订单的客户

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

输出:

HMqVde.png

分析:在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT 指出的是OUTER JOIN右边的表,LEFT指出的是OUTER JOIN左边的表)。

使用带聚集函数的联结

如果要检索所有客户及每个客户所下的订单数,下面使用了COUNT()函数的代码可完成此工作。

输入:

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

输出:

HMO5Ie.png

分析:此SELECT语句使用INNER JOIN 将Customers和Orders表互相关联。GROUP BY 子句按客户分组数据,因此,函数调用COUNT(Orders.order_num)对每个客户的订单计数,将它作为num_ord返回。

聚集函数也可以方便地与其他联结一起使用。

输入:

SELECT Customers.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;

输出:

HMjifH.png

使用联结和联结条件

  • 注意所使用的联结类型。一般我们使用内部联结,但使用外部联结也是有效的
  • 关于确切的联结语法,应该查看具体的文档
  • 应该总是提供联结条件,否则会出现笛卡尔积。

组合查询

组合查询

有两种基本情况,其中需要使用组合查询:

  • 在单个查询中不同的表类似返回结构数据。
  • 对单个表执行多个查询,按单个查询返回数据

创建组合查询

可用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集。

使用UNION

使用非常简单。所需要做的是给出每条SELECT语句,在各条语句之间放上关键字UNION。

如下所示,使用UNION语句连接

输入:

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';

输出:

HQZk9I.png

UNION规则

进行并时有几条规则需要注意:

  • UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔。
  • UNION中的每个查询必须包含相同的列、表达式、或聚集函数
  • 列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含转换的类型。
包含或取消重复的行

UNION从查询结果集中**自动除了重复的行。**在使用UNION时,重复的行被自动取消。

这是UNION的默认行为,但是如果愿意,可以改变它。事实上,如果想返回所有匹配行,可使用UNION ALL而不是UNION。

对组合查询进行排序

在使用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;

输出:

H80oO1.png

插入数据

数据插入

插入可以用几种方式使用:

  • 插入完整的行
  • 插入行的一部分
  • 插入某些查询的结果
插入完整的行

输入:

INSERT INTO Customers VALUES ('1000006','Toy Land','123 Any Street','New York','NY','1111','USA',NUll,NUll);

输出:

H8rpIf.png

但是上述的代码SQL语句很不安全。

编写INSERT语句的更安全的方法如下:

输入:

INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email)VALUES('1000007','Toy Land','123 Any Street','New York','NY','1111','USA',NUll,NUll);

输出:

H8rLkV.png

分析:DBMS将用VALUES列表中的相应值填入列表中的对应项。第二个值对应于第二个列名,依次类推。

插入部分行

输入:

INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)VALUES('1000008','Toy Land','123 Any Street','New York','NY','1111','USA');

输出:

H8y8V1.png

**注意:**在INASRT操作中省略某些列

  • 该列定义允许为NULL值
  • 在表定义中给出默认值,这表示如果不给出值,将使用默认值。
插入检索出的数据

INSERT一般用来给表插入一个指定的列。但是,INSERT还存在另一种形式,可以利用它将一条select语句的结果插入表中。这就是INASERT SELECT,它是由一条INSERT语句和一条SELECT语句组成的。

输入:

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;

输出:

由于没有创建CustNew表,所有没有输出。

从一个表复制到另一个表

有一种不使用INSERT语句的数据插入。为了将一个表的内容复制到一个全新的表,可使用SELECT INTO语句。

与INSERT SELECT不同的是,SELECT INTO将复制数据到一个新表中。

输入:

CREATE TABLE CustCopy AS SELECT * FROM Customers;

输出:

H82dYt.png

在使用SELECT INTO时,有一些需要知道的东西:

  • 任何SELECT选项和子句都可以使用,包括WHERE和GROUP BY。
  • 可以使用联结从多个表插入数据
  • 不管从多少个表检索数据,数据都只能插入到单个表中。

更新和删除数据

更新数据

为了更新表中的数据,可使用UPDATE语句。可采用两种方式使用UPDATE:

  • 更新表中特定行
  • 更新表中所有行

不要省略WHERE子句 在使用UPDATE时一定要细心。因为稍微不注意,就会更新表中的所有行。

基本的UPDATE语句由3部分组成,分别是:

  • 需要更新的表
  • 列名和它们的新值
  • 确定要更新哪些行的过滤条件

输入:更新单个列

UPDATE Customers SET cust_email = 'kim@thetoystore.com' WHERE cust_id = '1000000005';

分析:UPDATE 语句总是以要更新的表的名字开始。在上述例子中,需要更新的表的名字为Customers。SET命令用来将新值赋给被更新的列。UPDATE语句以WHERE子句结束。

输入:更新多个列

UPDATE Customers SET cust_contact = 'Sam Roberts',cust_email = 'sam@toyland.com' WHERE cust_id = '1000006';

分析:在更新多个列时,只需要使用单个SET命名,每个"列=值"对之间用逗号分隔。

删除数据

为了从一个表中删除数据,使用DELETE语句。可以两种方式使用DELETE:

  • 从表中删除特定的行
  • 从表中删除所有行

输入:从Customers表中删除一行

DELETE FROM Customers WHERE cust_id = '1000006';

DELETE语句从表中删除行。为了删除指定的列,使用UPDATE语句。

删除表的内容而不是表 DELETE语句从表中删除行,甚至时删除表中所有行。但是,DELETE不删除表本身。

更新和删除的指导原则

千万不要省略了WHERE子句,则UPDATE或DELETE将应用到表中所有的行。换句话说,如果执行UPDATE而不带WHERE子句,则表中每个行都将用新值更新。执行DELETE如果不带WHERE子句,表的所有数据都将被删除。

  • 除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE和DELETE语句。
  • 保证每个表都有主键,尽可能像WHERE子句那样使用它
  • 在对UPDATE或DELETE语句使用WHERE子句前,应该先用SELECT进行测试,保证它过滤的是正确的记录,以防编写的WHERE子句不正确。

创建和操控表

创建表

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

  • 多数DBMS都具有交互式创建和管理表的工具
  • 表也可以直接使用SQL语句操纵
表创建基础

使用CREATE TABLE创建表,必须给出下列信息:

  • 新表的名字,在关键字CREATE TABLE之后给出;
  • 表列的名字和定义,用逗号分隔

输入:

CREATE TABLE Products1
(
   prod_id CHAR(10)  NOT NULL,
	 vend_id CHAR(10)  NOT NULL,
	 prod_name CHAR(254)  NOT NULL,
	 prod_price DECIMAL(8,2) NOT NULL,
	 prod_desc varchar(1000)  NULL
);

分析:表名紧跟在CREATE TABLE关键字后面。

使用NULL值

NULL值就是没有值或缺值。允许NULL值的列也允许在插入行时不给出该列的值。不允许NULL值得列不接受该列没有值的行。

输入:

CREATE TABLE Orders(
  order_num INTEGER  NOT NULL,
  order_date DATEIME NOT NULL,
  cust_id CHAR(10)  NOT NULL
);

分析:每个列都含有关键字NOT NULL。这将会阻止插入没有值的列。

主键和NULL值 主键是其值唯一标识表中每一行的列。只有不允许NULL值的列可用于主键。

理解NULL 不要把NULL值与空串相混淆。NULL值是没有值;它不是空串。如果指定 ’ '(两个单引号,其间没有字符),这在NOT NULL列中是允许的。空串是一个有效的值,它不是无值。

指定默认值

SQL允许指定默认值,在插入行时如果不给出值,DBMS将自动采用默认值。默认值在CREATE TABLE语句的列定义中用关键字DEFAULT指定。

CREATE TABLE OrdersItems
(
  order_num INTEGER NOT NULL,
  order_item INTEGER NOT NULL,
   prod_id CHAR(10)  NOT NULL,
   quantity  INTEGER  NOT NULL DEDAULT 1,
   item_price DECIMAL(8,2) NOT NULL
);

MySQL用户指定时间使用DEFAULT CURRENT_DATE();

更新表

为了使用ALTER TABLE更改表结构,必须给出下面的信息:

  • 在ALTER TABLE 之后给出要更改的表名(该表必须存在,否则将出错)
  • 所做更改的表

输入:

ALTER TABLE Vendors
ADD vend_phone CHAR(20);

分析:这条语句给Vendors表增加一个名为vend_phone的列,其数据类型为CHAR

删除表

输入:

DROP TABLE CustCopy;

分析:删除CustCopy表。删除表没有确认,也不能撤销,执行这条语句将永久删除该表。

管理事务处理

事务处理

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

关于事务处理需要知道的几个术语:

  • 事务(transaction)指一组SQL语句
  • 回退(rollback)指撤销指定SQL语句的过程
  • 提交(commit)指将未存储的SQL语句结果写入数据库表
  • 保留点(savepoint)指事务处理中设置的临时占位符,你可以对他发布回退

控制事务处理

开启事务

输入:

START TRANSACTION
使用ROLLBACK

输入:

DELETE FROM Orders;
ROLLBACK;
使用COMMIT

一般的SQL语句都是直接针对数据库表执行和编写的。

输入:

BEGIN TRANSACTION
DELETE OrderItems WHERE order_num = 123456
DELETE Orders WHERE order_num= 123456
COMMIT TRANSACTION

分析:在这个SQL例子中,从系统中删除完全订单12345,因为涉及两个数据库表Orders和OrderItems,所有使用事务处理块来保证订单不被部分删除。最后的COMMIT语句仅在不出错时写出更改。

保留点

输入:

SAVEPOINT delete1

每个保留点都标取标识它的唯一名字,以便在回退时,DBMS知道要回退到何处。

了解高级SQL特性

约束:

管理如何插入或处理数据库数据的规则

主键

主键是一种特殊的约束,它用来保证一个列中的值是唯一的,并且永不改动。

表中任意列只要满足以下条件,都可以用于主键:

  • 任意两行的主键都不相同
  • 每行都有一个主键值(即列中不允许NULL值)
  • 包含主键值的列不修改或更新
  • 主键值不能重用。

定义主键的一种方法是创建它,如下:

CREATE TABLE Vendors
(
    vend_id CHAR(10) NOT NULL PRIMARY KEY,
    vend_name CHAR(50) NOT NULL,
    vend_address CHAR(50) NULL,
)

分析:在此例子中,给表的vend_id列定义添加关键字PRIMARY KEY,使其成为主键。

ALTER TABLE Vendors 
ADD CONSTRAINT PRIMARY KEY(vend_id);

分析:定义相同的列为主键,但使用的是CONSYRAINT语法。

外键

外键是表中的一个列,其值必须在另一表的主键中列出。

定义外键的一种方法:

CREATE TABLE Orders(
  order_num INTEGER NOT NULL PRIMARY KEY,
  order_date DATETIME NOT NULL,
  cust_id CHAR(10) NOT NULL REFERENCES  Customers(cust_id)
);

分析:其中的表定义使用了REFERENCES关键字,它标识cust_id中的任何值都必须是Customers表中的cust_id中的值。

索引

在创建索引之前,应该记住以下内容:

  • 索引改善检索操作的性能,但降低数据插入、修改和删除的性能。在执行这些操作时,DBMS必然动态地更新索引。
  • 索引数据可能要占用大量的存储空间
  • 并非所有数据都适合于索引。唯一性不好的数据从索引得到的好处不比具有更多可能值的数据从索引得到的好处多
  • 索引用于数据过滤和数据排序。如果你经常以某种特定的顺序排序数据,则该数据可能是索引的备选。

输入:

CREATE INDEX prod_name_ind
ON PRODUCTS (prod_name);

分析:索引必须唯一命名。这里的索引名在关键字CREATE INDEX之后定义。ON用来指定被索引的表,而索引中的列在表名后的圆括号中给出。

附录:

上述例子中对应的数据库语句

创建对应的表:

--------------------------------------------
-- Sams Teach Yourself SQL in 10 Minutes
-- http://www.forta.com/books/0672325675/
-- Example table creation scripts for MySQL.
--------------------------------------------


-------------------------
-- Create Customers table
-------------------------
CREATE TABLE Customers
(
  cust_id      char(10)  NOT NULL ,
  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 
);

--------------------------
-- Create OrderItems table
--------------------------
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 
);


----------------------
-- Create Orders table
----------------------
CREATE TABLE Orders
(
  order_num  int      NOT NULL ,
  order_date datetime NOT NULL ,
  cust_id    char(10) NOT NULL 
);

------------------------
-- Create Products table
------------------------
CREATE TABLE Products
(
  prod_id    char(10)      NOT NULL ,
  vend_id    char(10)      NOT NULL ,
  prod_name  char(255)     NOT NULL ,
  prod_price decimal(8,2)  NOT NULL ,
  prod_desc  text          NULL 
);

-----------------------
-- Create Vendors table
-----------------------
CREATE TABLE Vendors
(
  vend_id      char(10) NOT NULL ,
  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 
);


----------------------
-- Define primary keys
----------------------
ALTER TABLE Customers ADD PRIMARY KEY (cust_id);
ALTER TABLE OrderItems ADD PRIMARY KEY (order_num, order_item);
ALTER TABLE Orders ADD PRIMARY KEY (order_num);
ALTER TABLE Products ADD PRIMARY KEY (prod_id);
ALTER TABLE Vendors ADD PRIMARY KEY (vend_id);


----------------------
-- Define foreign keys
----------------------
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);

插入的数据:

----------------------------------------------
-- Sams Teach Yourself SQL in 10 Minutes
-- http://www.forta.com/books/0672325675/
-- Example table population scripts for MySQL.
----------------------------------------------


---------------------------
-- Populate Customers table
---------------------------
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', 'sales@villagetoys.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH', '43333', 'USA', 'Michelle Green');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'jjones@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Denise L. Stephens', 'dstephens@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard');

-------------------------
-- Populate Vendors table
-------------------------
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRS01','Bears R Us','123 Main Street','Bear Town','MI','44444', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRE02','Bear Emporium','500 Park Street','Anytown','OH','44333', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('DLL01','Doll House Inc.','555 High Street','Dollsville','CA','99999', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FRB01','Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FNG01','Fun and Games','42 Galaxy Road','London', NULL,'N16 6PS', 'England');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('JTS01','Jouets et ours','1 Rue Amusement','Paris', NULL,'45678', 'France');

--------------------------
-- Populate Products table
--------------------------
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR01', 'BRS01', '8 inch teddy bear', 5.99, '8 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR02', 'BRS01', '12 inch teddy bear', 8.99, '12 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR03', 'BRS01', '18 inch teddy bear', 11.99, '18 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG01', 'DLL01', 'Fish bean bag toy', 3.49, 'Fish bean bag toy, complete with bean bag worms with which to feed it');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG02', 'DLL01', 'Bird bean bag toy', 3.49, 'Bird bean bag toy, eggs are not included');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG03', 'DLL01', 'Rabbit bean bag toy', 3.49, 'Rabbit bean bag toy, comes with bean bag carrots');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RGAN01', 'DLL01', 'Raggedy Ann', 4.99, '18 inch Raggedy Ann doll');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL01', 'FNG01', 'King doll', 9.49, '12 inch king doll with royal garments and crown');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL02', 'FNG01', 'Queen doll', 9.49, '12 inch queen doll with royal garments and crown');

------------------------
-- Populate Orders table
------------------------
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20005, '2004-05-01', '1000000001');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20006, '2004-01-12', '1000000003');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20007, '2004-01-30', '1000000004');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20008, '2004-02-03', '1000000005');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20009, '2004-02-08', '1000000001');

----------------------------
-- Populate OrderItems table
----------------------------
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 1, 'BR01', 100, 5.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 2, 'BR03', 100, 10.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 1, 'BR01', 20, 5.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 2, 'BR02', 10, 8.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 3, 'BR03', 10, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 1, 'BR03', 50, 11.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 2, 'BNBG01', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 3, 'BNBG02', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 4, 'BNBG03', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 5, 'RGAN01', 50, 4.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 1, 'RGAN01', 5, 4.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 2, 'BR03', 5, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 3, 'BNBG01', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 4, 'BNBG02', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 5, 'BNBG03', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 1, 'BNBG01', 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 2, 'BNBG02', 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 3, 'BNBG03', 250, 2.49);

d, quantity, item_price)
VALUES(20006, 2, ‘BR02’, 10, 8.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 3, ‘BR03’, 10, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 1, ‘BR03’, 50, 11.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 2, ‘BNBG01’, 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 3, ‘BNBG02’, 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 4, ‘BNBG03’, 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 5, ‘RGAN01’, 50, 4.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 1, ‘RGAN01’, 5, 4.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 2, ‘BR03’, 5, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 3, ‘BNBG01’, 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 4, ‘BNBG02’, 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 5, ‘BNBG03’, 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 1, ‘BNBG01’, 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 2, ‘BNBG02’, 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 3, ‘BNBG03’, 250, 2.49);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值