sql查询相同数据序号递增_运⽤SQL对数据进⾏复杂查询
⼀、视图
1.1 定义
从 SQL的⾓度来看,视图就是⼀张表。实际上,在SQL语句中并不需要区分哪些是表, 哪些是视图,只需要知道在更新时它们之间存在从 SQL的⾓度来看,视图就是⼀张表
视图和表的区别只有⼀个,那就是“是否保存了实际的数据”。 通常,我们在创建表时,会通过INSERT语句将数⼀些不同就可以了。视图和表的区别只有⼀个,那就是“是否保存了实际的数据”
通过SELECT语句查询数据
据保存到数据库之中,⽽数据库中的数据实际上会被保存到计算机的存储设备(通常是硬盘)中。因此,我们通过SELECT语句查询数据
时,实际上就是从存储设备(硬盘)中读取数据,进⾏各种计算之后,再将结果返回给⽤户这样⼀个过程。 但是使⽤视图时并不会将数据时,实际上就是从存储设备(硬盘)中读取数据
视图保存的是 SELECT 语句。我们从视图中读取数据时,视图会在保存到存储设备中,⽽且也不会将数据保存到其他任何地⽅。实际上视图保存的是 SELECT 语句
内部执⾏该 SELECT 语句并创建出⼀张临时表。
因此,视图是虚拟的表。与包含数据的表不⼀样,视图只包含使⽤时动态检索数据的查询。此外,视图中存放的不是数据,⽽是SQL查询语
句。
1.2 创建视图
⽅法⼀:使⽤语句创建视图
CREATE VIEW [view name]([column name1], [column name2],... [column nameN])
AS
SELECT [column name1], [column name2],... [column nameN]
FROM [table name]
...;
⽅法⼆:在客户端中创建视图
进⼊数据库实例管理界⾯,展开要增加视图的数据库实例 -> 右击【Views】 -> 点击【Create View】-> 进⼊视图编辑界⾯,输⼊查询语
句,点击【Apply】-> 右击【Views】 -> 点击【Refresh All】。
1.3 使⽤创建好的视图
在FROM⼦句中使⽤视图名称代替表名称即可。
举例:以下查询⽤来检索订购了某种产品的顾客。
SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
der_num = der_num;
现在,把整个查询包装成⼀个名为ProductCustomers的虚拟表,则可以如下轻松地检索出相同的数据:
SELECT cust_name, cust_contact FROM ProductCustomers
WHERE prod_id = 'RGAN01';
这条语句通过WHERE⼦句从视图中检索特定数据。当MySQL处理此查询时,它将指定的WHERE⼦句添加到视图查询中已有的WHERE ⼦句中,以便正确过滤数据。 可以看出,视图极⼤地简化了复杂
SQL语句的使⽤。利⽤视图,可⼀次性编写基础的SQL,然后根据需要多次使⽤。
1.4 删除视图
⽅法⼀:使⽤语句删除视图
DROP VIEW [view name];
⽅法⼆:在客户端中删除视图
选中想要删除的视图 -> 右击选择【】
1.5 视图的好处
视图⽆需保存数据,因此可以节省存储设备的容量。
重复使⽤SQL语句,简化复杂的SQL操作。
视图中的数据可以随原数据表的改变⽽更新,因为视图存放的不是视图,⽽是查询语句。因此,每次使⽤视图时,视图都需要从原数据表中调⽤数据。
可节省存放数据的空间,因为视图不需要保存数据。
保护数据。因为视图使⽤的是表的⼀部分⽽不是整个表,因此可授予⽤户访问表的特定部分权限,⽽不是整个表的访问权限。
1.6 注意事项
定义视图时不能使⽤ORDER BY⼦句,因为视图和表⼀样,数据⾏都是没有顺序的
避免在视图的基础上再去创建视图,因为多重视图会降低SQL的性能和效率
不能往视图中插⼊数据
必须唯⼀命名,即不能给视图取与别的视图或表相同的名字
创建视图必须具有⾜够的访问权限。这些权限通常由数据库管理⼈员授予。
⼆、⼦查询
2.1 定义
⼦查询可以看作是⼀次性的视图,即在SQL中直接写定义视图的查询语,也可以理解为在⼀个SELECT查询语句中嵌套了另⼀个SELECT查询语句。
SQL运⾏顺序:先运⾏⼦查询,再运⾏外部的查询语句。
2.2 ⼦查询的使⽤
(1) 利⽤⼦查询进⾏过滤:在WHERE语句后使⽤IN(⼦查询)、 ANY(⼦查询)、 ALL(⼦查询)或者SOME(⼦查询)。
(2) 作为计算字段使⽤⼦查询。假如需要显⽰学⽣信息及每个学⽣的选课数:
SELECT *, (
SELECT COUNT(*) AS 'number_of_classes' FROM scores
WHERE students.id = scores.id) AS counts
FROM students;
2.3 练习
练习⼀:哪些学⽣的成绩⽐课程0002的任意成绩都⾼呢?
SELECT * FROM scores
WHERE score >
ANY(SELECT score FROM scores WHERE c_id = '0002');
练习⼆:哪些学⽣的成绩⽐课程0002的所有成绩都⾼呢?
⽅法⼀:
SELECT * FROM scores
WHERE score >
ALL(SELECT score FROM scores WHERE c_id = '0002');
⽅法⼆:
USE interview;
SELECT * FROM scores
WHERE score > (SELECT MIN(score) FROM scores WHERE c_id = '0002');
2.4 注意事项
作为⼦查询的 SELECT 语句只能查询单个列,企图检索多个列将返回错误。
尽量避免⼦查询嵌套,因为会降低代码的性能和可读性
ANY(⼦查询)、 ALL(⼦查询)以及SOME(⼦查询)不可以做算术运算,因为得到的不是⼀个数组,⽽是集合,因此需要把算术运算放在运算符左边。
三、标量⼦查询
3.1 定义:返回单⼀值的⼦查询
标量就是单⼀的意思。 在本⽂中第⼆部分提到的⼦查询基本上都会返回多⾏结果(虽然偶尔也会只返回1⾏数据)。⽽标量⼦查询则有⼀个特必须⽽且只能返回 1 ⾏ 1 列的结果
列的结果,也就是返回表中某⼀⾏的某⼀列的值,例如“23”或者“北京市”这样的值。由殊的限制,那就是必须⽽且只能返回 1 ⾏ 1
标量⼦查询的返回值可以⽤在 = 或者 <> 这样需要单⼀值的⽐较运算符之中。
于返回的是单⼀的值,因此标量⼦查询的返回值可以⽤在 = 或者 <> 这样需要单⼀值的⽐较运算符之中
此外,标量⼦查询的书写位置并不仅仅局限于WHERE ⼦句中,通常任何可以使⽤单⼀值的位置都可以使⽤。也就是说,能够使⽤常数或者列名的地⽅,⽆论是 SELECT ⼦句、GROUP BY ⼦句、HAVING ⼦句,还是 ORDER BY⼦句,⼏乎所有的地⽅都可以使⽤。
mysql删除重复的数据保留一条例如,在SELECT⼦句中使⽤计算平均分数的标量⼦查询的SQL语句:
SELECT id, score,
(SELECT AVG(score) FROM scores) AS 'average_score'
FROM scores;
此外,我们还可以在 HAVING ⼦句中使⽤标量⼦查询:
SELECT id, AVG(score) AS 'average_score' FROM scores
GROUP BY id
HAVING AVG(score) >
(SELECT AVG(score) FROM scores);
3.2 练习
练习⼀:差⽣为成绩<=60分的学⽣,优等⽣为成绩>80分的学⽣。查询成绩介于差⽣平均成绩和优等⽣平均成绩之间的学⽣学号及成绩
SELECT id, score FROM scores
WHERE score BETWEEN
(SELECT AVG(score) FROM scores
WHERE score <= 60)
AND
(SELECT AVG(score) FROM scores
WHERE score > 60);
3.3 注意事项
该⼦查询绝对不能返回多⾏结果。也就是说,如果⼦查询返回了多⾏结果,那么它就不再是标量⼦查询,⽽仅仅是⼀个普通的⼦查询了,因此不能被⽤在 = 或者 <> 等需要单⼀输⼊值的运算符当中,也不能⽤在 SELECT 等⼦句当中。
四、关联⼦查询
4.1 定义
关联⼦查询和GROUP BY⼦句⼀样,也可以对表中的数据进⾏切
关联⼦查询在细分的组内进⾏⽐较时使⽤。换⼀个⾓度来理解,关联⼦查询和GROUP BY⼦句⼀样,也可以对表中的数据进⾏切
关联⼦查询在细分的组内进⾏⽐较时使⽤
分。例如,出每门课程中成绩⾼于对应课程平均分的学⽣:
SELECT id FROM scores AS a
WHERE score >
(SELECT AVG(score) FROM scores AS b
WHERE a.c_id = b.c_id
GROUP BY c_id);
这⾥起到关键作⽤的就是在⼦查询中添加的WHERE⼦句的条件。该条件的意思就是,在同⼀门课程中对各学⽣的成绩和平均成绩进⾏⽐关联⼦查询的结合条件如果未出现在⼦查询之中就会发⽣错误。这是因为⼦查询内部设定的关联名称,只能在该⼦较。 需要注意的是,关联⼦查询的结合条件如果未出现在⼦查询之中就会发⽣错误。
“内部可以看到外部,⽽外部看不到内部”。 如前所述,SQL 是按照先内层⼦查询后外层查询的顺序来查询内部使⽤。换句话说,就是“内部可以看到外部,⽽外部看不到内部”
执⾏的。这样,⼦查询执⾏结束时只会留下执⾏结果,作为抽出源的b表其实已经不存在了。因此, 如果没有将查询的结合条件放在内层⼦查询中,在执⾏外层查询时,由于b表已经不存在了,因此就会返回“不存在使⽤该名称的表”这样的错误。
4.2 应⽤
4.2.1 累计值
把截⽌到某个时间点且按时间记录的数值累加⽽得出来的数值称为累计值。例如下⾯有⼀张银⾏账户存取款历史记录表 Accounts,其把截⽌到某个时间点且按时间记录的数值累加⽽得出来的数值称为累计值
中,处理⾦额为正数代表存钱,为负数代表取钱。现在我们想通过 SQL 查询语句求出累计值。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论