《Sam Teach Yourself SQL in 10 Minutes》学习笔记(4)

--组合查询
--多数SQL查询都只包含一个或多个表中返回数据的单条SELECT语句。但是,SQL也允许执行多个查询(多条SELECT语句),并将结果作为单个结果集返回。这些组合查询通常称为是并(union)或复合查询(compound query)。
--在单个查询中从不同的表类似返回结构数据
--对单个表执行多个查询,按单个查询返回数据
--组合查询和多个WHERE条件   多数情况下,组合相同表的两个查询完成的工作与具有多个WHERE子句的单条查询完成的工作相同。换句话说,任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询给出,下面例子可以看到:
--14.2  创建组合查询
--可用UNION操作符来组合多条SQL查询
--14.2.1使用UNION    所需做的只是给出每条SELECT语句,在各条语句之间放上关键字UNION.
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_state IN ('IL', 'IN', 'MI');
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_name = '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';
----也可以使用多条WHERE子句而不是使用UNION的相同查询:
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_state IN ('IL', 'IN', 'MI')
--OR cust_name = 'Fun4All';
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_state IN ('IL', 'IN', 'MI')
--UNION
--SELECT cust_name, cust_contact			--使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式。
--FROM Customers
--WHERE cust_name = 'Fun4All';
--在这个简单的例子中,使用UNION可能比使用WHERE子句更为复杂。但对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据的情形,使用UNION可能会使处理更简单。
--UNION的限制   对于使用UNION组合的SELECT语句数目,不存在标准的SQL限制。
--性能问题    理论上使用多条WHERE子句条件或UNION应该没有实际的差别,但是可以性能上会有所不同。
--14.2.2  NUION规则
--UNION必须有两台或两台以上的SELECT语句组成,语句之间用关键字UNION分隔。
--UNION中的每个查询必须包含相同的列,表达式或聚集函数(不过各个列不需要以相同的次序列出)。
--列数据类型必须兼容:类型不必完全相同,但必须使DBMS可以隐含地转换的类型(例如:不同的数值类型或不同的日期类型)
--14.2.3  包含或取消重复的行
--UNION从查询结果集中自动去除了重复的行(它的行为与单条SELECT语句中使用多个WHERE子句条件一样)
--这个UNION默认行为。如果想返回所有匹配行,可使用UNION ALL而不是UNION.
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_state IN ('IL', 'IN', 'MI')
--UNION ALL
--SELECT cust_name, cust_contact, cust_email
--FROM Customers
--WHERE cust_name = 'Fun4All';		--重复的行也进行的输出
--使用UNION ALL,DBMS不取消 重复的行。
--UNION与WHERE   UNION几乎总是完成与多个WHERE条件相同的工作。UNION ALL为UNION的一种形式,它完成WHERE子句完成不了的工作。如果确实需要每个条件的匹配行全部出现(包括重复行),则必须使用UNIONA ALL而不是WHERE。
--14.2.4 对组合查询结果排序
--在用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;

--SELECT cust_name, cust_contact, cust_email		--结果为什么不一致
--FROM Customers
--WHERE cust_state IN ('IL', 'IN', 'MI')
--UNION
--SELECT cust_name, cust_email, cust_contact		--每条 SELECT 语句中的列的顺序必须相同。
--FROM Customers
--WHERE cust_name = 'Fun4All'
--ORDER BY cust_name, cust_contact;
--14.3 小结
--UNION,可以把多条查询的结果作为一条组合查询返回,不管它们的结果中包含还是不包含重复。使用UNION可极大地简化复杂地WHERE子句,简化从多个表中检索数据的工作。

--15  插入数据
--15.1.1 插入完整的行
--把数据插入表中的最简单的方法时使用基本的INSERT语法,它要求指定表名和被插入到新行中的值。
--INSERT INTO Customers
--VALUES('1000000006',
--	   'Toy Land',
--	   '123 Any Street',
--	   'New Tork',
--	   'NY',
--	   '11111',
--	   'USA',
--	   'NULL',
--	   'NULL');
--存储到每个表列的中的数据在VALUES子句中给出,对每个列必须提供一个值。如果某个列没有值(如上面的cust_contact, cust_email列),应该使用NULL值(假定表允许对该列指定空值)。各个列必须以它们在表定义中出现的次序填充。
--INTO关键字		在某些SQL实现中,跟在INSERT之后的INTO关键字时可选的。
--虽然这种语法很简单,但并不安全,应该尽量避免使用。上面的SQL语句高度依赖于表中的列的定义次序,并且还依赖于其次序容易获得的信息。即使可得到这种次序信息,也不能保证下一次表结构变动后各个列保持完全相同的次序。因此,很不安全的,难免会出问题。
--编写INSERT语句的更安全(不过更繁琐)的方法如下:
--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');
--此例子完成与前一个INSERT语句完全相同的工作,但在表明后的括号里明确地给出了列名。在插入行时,DBMS将用VALUES列表中的相应值填入列表中的对应值。
--因为提供了列名,VALUES必须以其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序。其优点是,即使表的结构改变,此INREST语句仍然能正确工作。
--总是使用列的列表  一般不要使用没有明确给出列的列表的INSERT语句。使用列的列表能使SQL代码继续发挥作用,即使表结构发生了变化。
--仔细地给出值	不管使用哪种INSERT语法,都必须给出数目正确的值。如果不提供列名,则必须给每个表列提供一个值。如果提供列名,则必须对每个列出的列给出一个值。如果不这样,将产生一条错误消息,对应的行插入不成功。
--15.1.2  插入部分行
--正如所述,使用INSERT的推荐方法是明确给出表的别名。使用这种语法,还可以省略列。这表示可以只给某些列提供值,给其他列不提供值。
--INSERT INTO Customers(cust_id,
--		cust_name,
--		cust_address,
--		cust_city,
--		cust_state,
--		cust_zip,
--		cust_country)
--VALUES('1000000006',
--		'Toy Land',
--		'123 Any Street',
--		'New York',
--		'NY',
--		'11111',
--		'USA');
--前面给出的例子中,对两个列cust_contact, cust_email没有提供值。这表示没必要将它们包含在INSERT语句中。因此,这里的INSERT语句省略了这两个列和对应的值。
--省略列  如果表的定义允许,则可以在INSERT操作中省略某些列。省略的列必须满足以下某各条件:
--该列定义为允许NULL值(无值或空值)。
--在表定义中给出默认值。这表示如果不给出值,将使用默认值。
--如果对表中不允许NULL值且没有默认值的列不给出值,则DBMS将产生一条错误信息,并且相应的行插入不成功。
--15.1.3 插入检索出的数据
--INSERT一般用来给表插入一个指定列值的行。但是,INSERT还存在另一种形式,可以利用它将一条SELECT语句的结果插入表中。这就是所谓的INSERT SELECT,顾名思义,它是由一条INSERT语句和一条SELECT语句组成的。
--新例子的说明 从CustNew表中读取数据,故首先创建和填充CustNew表。在填充CustNew时,不应该使用已经在Customers中使用过的cust_id(如果主键值重复,后续的INSERNT操作将会失败)。
--INSERT INTO Customers(cust_id,
--			cust_contact,
--			cust_email,
--			cust_address,
--			cust_city,
--			cust_state,
--			cust_zip,
--			cust_country)
--SELECT	cust_id,
--		cust_contact,
--		cust_email,
--		cust_address,
--		cust_city,
--		cust_state,
--		cust_zip,
--		cust_country
--FROM CustNew;
--INSERT SELECT的别名  为简单起见,这个例子在INSERT和SELECT语句中使用了相同的列名。但是,不一定要求列名匹配。事实上,DBMS甚至不关心SELECT返回的列名。它使用的时是列的位置,因此SELECT中的第一列(不管其列名)将用来填充表列中指定的第一个列。
--INSERT SELECT中SELECT的语句可包含WHERE子句以过滤插入的数据。
--插入多行		INSERT通常只插入一行。为了插入多行,必须执行多个INSERT语句。INSERT SELECT是个例外,它可以用单条INSERT插入多行,不管SELECT语句返回多少行,都将被INSERT插入。
--15.2 从一个表复制到另一个表
--有一种不使用INSERT语句的数据插入。为了将一个表的内容复制到一个全新的表(在运行中创建的表),可使用SELECT INTO语句。
--与INSERT SELECT增补数据到一个已经存在的表不同,SELECT INTO将复制数据到一个新表(有的DBMS可以覆盖已经存在的表,依赖于具体的DBMS)。
--INSERT SELECT与SELECT INTO 它们之间的一个重要差别是新者导出数据,而后置导入表。
--SELECT *			--要想只复制列的子集,可明确地给出列名而不是使用*通配符。 如果没有该表,则会自动创建。
--INTO CustCopy
--FROM Customers;
--在使用SELECT INTO时,有一些需要知道的东西:
--如何SELECT选项和子句都可以使用,包括WHERE和GROUP BY。
--可利用联结从多个表插入数据
--不管从多个表中检索数据,数据都只能插入到单个表中。
--进行表的复制    SELECT INTO时试验新SQL语句前,做表复制的很好的工具,不会影响到实际的数据。
--15.3 小结
--如何用INSERT SELECT从其它表中导入表,如何用SELECT INT将行到处到一个新表。








 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值