SQL学习--Select(一)TOP、派生表、连接、谓词

TOP关键字

1 select top 4 WITH TIES t.title,sum(s.qty)as totalSales from sales s
2 left join titles t on s.title_id=t.title_id
3 group by t.title
4 order by totalSales

这里的top 4 WITH TIES 是获取前4条数据且需要重复值,但是请注意这个重复值是会影响返回数据的行
比如,重复值在第4行出现那么可能就会返回5行数据(2个值的重复)
如果重复值在第二行或者第三行出现则只返回4条数据
另外需要注意的TOP N WITH TIES...需要与order by一同使用否则会报错。

TOP N的缺点

  无法返回与查询的GroupBy子句中的被分组的结果集的前几条,
  这就标明TOP N指向的是整个查询的结果集,而不是指向源表中或已被分类的组中的行。
  TOP N的运算顺序在整个sql关键字的后边。实例:

1 select t.state,t.stor_name,sum(s.qty)as totalSales
2 from sales s join stores as t on s.stor_id=t.stor_id
3 group by t.state,t.stor_name
4 order by totalSales desc
5
6 select top 1 t.state,t.stor_name,sum(s.qty)as totalSales
7 from sales s join stores as t on s.stor_id=t.stor_id
8 group by t.state,t.stor_name
9 order by totalSales desc

派生表

  select除了直接引用表或试图外还可以使用派生表(子查询),也叫逻辑表。它可以像表或视图一样查询和链接

select au_lname,au_fname from (select * from authors) as a

  这个派生表是由select * from authors语法创建的,此处可以插入任何一个有效的查询,

  但需要注意这里使用别名且必须使用别名。因为T-SQL支持非列表的Select语句。

1 select * from (
2     select ‘Blotchet-Halls‘ as weightClass ,0 as lowBound ,112 as highBound
3     union all
4     select ‘DeFrance‘ as weightClass ,112 as lowBound ,118 as highBound
5     union all
6     select ‘Green‘ as weightClass ,127 as lowBound ,135 as highBound
7 )as w
8 order by w.lowBound

  例子中这个表不存在只是通过union all链接形成了一张逻辑表,逻辑表同时可以与表或试图相连接

连接

  在内连接中,从句顺序s不会影响到结果集。如果A等于B,那么B就等于A。

而在外连接中则不然,表中的顺序直接影响结果集中包含的哪些行及值

1 select sum(d.UnitPrice*d.Quantity) as totalOrders from Orders o
2 left join [Order Details] d on o.OrderID+10=d.OrderID
3 left join Products p on d.ProductID=p.ProductID
4
5 select sum(d.UnitPrice*d.Quantity) as totalOrders from [Order Details] d
6 left join Products p on d.ProductID=p.ProductID
7 left join [Orders] o on o.OrderID+10=d.OrderID
8 --连接部分的先后顺序改变了

在例子中故意把OrderID+10造成不匹配,观察两次查询的运算结果,并不相同。

因为第一个查询中引起的表Orders和Order Details的不匹配是在对列UnitPrice*Quantity汇总前,

而第二个查询的不匹配是发生在汇总后。第二个查询的情况下,会得到所有Details中的所有项的总和,

无论他与Orders是否匹配,而在第一个查询中就不是这样了。

看一下在2个查询中不匹配的数据有哪些

1 select o.OrderDate,d.UnitPrice,d.Quantity from Orders o
2 left join [Order Details] d on o.OrderID+10=d.OrderID
3 left join Products p on d.ProductID=p.ProductID
4 where o.OrderDate is null or d.UnitPrice is null

执行语句后,会发现正是我通过OrderID+10的那10条数据。

所以在使用外部链接存在不匹配链接的可能,所以一定要小心。

谓词

  BETWEEN

    他的作用是判断一个给定值是否落在了两个值之间的内部

1 select au_lname,au_fname from authors
2 where au_lname between ‘s‘ and ‘zz‘
3 order by au_lname

带有子集、变量和表达式的语句

1 Declare @au_id id
2 select @au_id=(select max(au_id) from titleauthor)
3
4 select au_lname,au_fname from authors
5 where au_id between (select min(au_id) from titleauthor) and (ISNULL(@au_id,‘zzzzzzzzzzzzz‘))
6 order by au_lname

尽管BetWEEN...AND很方便,但有时候很难界定多个区间的范围。此时不如用逆向思维排除法,扣去必定发生的,就能得到不会发生的

  LIKE

  检测一个值对字符串的模式匹配

  %:表示匹配任意字符

  _:表示只匹配一个字符

  [ab]:表示匹配a、b、ab

  EXISTS

  把子查询作为单独参数返回的判断函数。在EXISTS前边加NOT表示否定

  EXISTS在指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中

  如果成立则返回true不成立则返回false。如果返回的是true的话,则该行结果保留,如果返回的是false的话,则删除该行,最后将得到的结果返回。

  在EXISTS中NULL值的处理

1 select title from titles t
2 where EXISTS(--此时为true
3     select * from(
4         select *from sales
5         union all
6         select null,null,null,90,null,null
7     ) s--通过union all插入了一条为null,qty为90的数据
8 where t.title_id=s.title_id and s.qty>75)

  这个查询结果最后还是空。为什么呢?最后插入的null的那条数据是满足where qty>75的为什么没有返回?

  答案是即便是返回了但是连接条件是titleid=titleid,而插入的数据titleID=null,null怎么可能等于null呢?null谁都不等于,也不等于自己

  EXISTS和IN

  把EXISTS换成IN有一些特殊性。

1 select Count(title) from titles t
2 where t.title_id in(select title_id from sales)--16条
3
4 select Count(title) from titles t
5 where t.title_id not in(select title_id from sales)--2条
6
7 select Count(title) from titles t
8 where t.title_id not in(select title_id from sales union all select null)--0条

  IN在比较一个值与NULL是否相等的表达式总是返回NULL,所以不符合检测,原因是其他行与null在同一列表所以返回null。这是IN和EXISTS的区别

  另外如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

  如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。

  同时不管使用哪种子查询的方式都是比表连接要慢很多的,所以建议使用连接的方式。

  结果集为空

  EXISTS的另外一种用法是检测结果集的多行。

  if exists(select * from sales)肯定要比if(select count(*) from sales )>0快的多,而且提供了一种不检查系统对象来确定表是否为空的快速方法

  where和having以外的EXISTS

  EXISTS还可以做很多其他的工作,不仅仅是查询返回的行。通过派生表还可以在case表达式和from子句中

  select case when EXISTS(Select * from titleauthor where au_id=a.au_id) then ‘true‘ else ‘false‘ end from authors a

 IN

1 select * from titles where title_id in
2 (
3     select title_id from (
4         select top 99999 title_id,count(*) as numberOrder from sales group by title_id order by numberOrder desc
5     )s
6 )

  

原文地址:https://www.cnblogs.com/cuijl/p/8598013.html

时间: 2024-10-10 07:44:12

SQL学习--Select(一)TOP、派生表、连接、谓词的相关文章

SQL学习_查询重复数据和连接多个表数据的方法

进行数据库测试时需要根据不同场景查询数据,以便验证发现的问题是否为脏数据引起的.记录一下最近常用的查询方法: 1. 查询表中重复数据(id不同,多个字段值相同) select P1.* from project as P1, project as P2 where P1.id<>P2.id and P1.ProjectId=P2.ProjectId and P1.ServiceTypeId=P2.ServiceTypeId and P1.Rank=P2.Rank 2.连接多个表数据 selec

SQL笔记-第七章,表连接

SQL中使用JOIN 关键字来使用表连接.表连接有多种不同的类型,被主流数据库系统支持的有交叉连接(CROSS JOIN).内连接(INNER JOIN).外连接(OUTTER JOIN),另外在有的数据库系统中还支持联合连接(UNION JOIN). 一.内连接(INNER JOIN) SELECT FNumber,FPriceFROM T_Order INNER JOIN T_CustomerON FCustomerId= T_Customer.FIdWHERE T_Customer.FNa

(MYSQL学习笔记2)多表连接查询

3种连接方式的区别: INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录. RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录. 3个表连接查询,语句如下: SELECT a.YHID,a.TDID,b.YHMC,b.YHZH,c.TDMC FROM (km_tdcy a LEFT JOIN km_xtyh b ON a.YHID=b

SQL学习系列(一)之多表查询

在数据库中,各个表之间存在一定的联系,如果需要对数据进行一系列的查询是,仅仅从一个表或一个库中获得数据信息是不够的,需要从多个表或多个数据库提取所需要的数据信息,而进行一些简单select语句查询是无法满足用户需求的,这时就需要涉及到高级查询. 以下都用A.B代表数据库表. 1.内连接查询-内连接使用比较运算符对各个表中的数据进行比较操作,并列出各个表中与条件相匹配的所有数据行. 关键字:INNER JOIN或JOIN (1).等值连接 语句格式:select a * ,b * from A a

SQL学习(五)多表关联-join

在实际工作中会用到多表联查,此时需要用到关键字JOIN 一.inner join(内连接) 至少有一个匹配时返回行,只返回两个表中连接字段相等的行 如: select * from ticket inner join job on ticket.id=job.t_id 只查询出,ticket.id=job.t_id的数据 二.left join(左连接) 即使右表中没有匹配,也从左表中返回所有的行 如: select * from ticket left join job on ticket.i

表连接到底咋回事,就是产生中间结果啊!用于给select/insert等操作用

1.表连接到底咋回事,就是产生中间结果啊!用于给select/insert等操作用啊. 2.表连接产生的结果用于select/insert用 3.表连接产生的结果用于select/insert用 比如: sql = "select [个人信息$].*,[工作经历$].* from [个人信息$] inner Join [工作经历$] on [个人信息$].UID=[工作经历$].UID" 将表连接产生的中间结果用于select/insert操作等用 对比于传统的多表查询采用笛卡尔积,如

每天一点数据库之-----Day 9 表连接

每天一点数据库之-----Day 9 表连接 ----转载请注明出处:coder-pig 本节引言: 前面我们学习的都是针对一个表来进行操作的,上一节虽然学了UNION这个可以操作多个表 的关键字,但是又有两个限制(查询字段数目与数据类型要相同),本节就来学习通过表连接 来操作多个表!而表连接又有四种: 内连接,外连接,交叉连接与自连接,那么接下来开始本节学习! 数据准备: 在开始学习前,我们先准备一些数据,建三个表:T_Stu,T_Class,T_Dorm 建T_Stu表: CREATE TA

深入理解Oracle表(3):三大表连接方式详解之Nested loop join和 Sort merge join

深入理解Oracle表(3):三大表连接方式详解之Nested loop join和 Sort merge join 分类: Oracle 基础管理 Oracle SQL 开发2013-01-28 00:33 2536人阅读 评论(1) 收藏 举报 关系数据库技术的精髓就是通过关系表进行规范化的数据存储       并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理       这里Think愿意和大家一起来学习分享Oracle的三大表连接技术              在早期版本,

SQL Server进阶(六)表表达式

概述 SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 派生表 派生表是一个查询结果生成的表,类似于临时表. 派生表可以简化查询,避免使用临时表.相比手动生成临时性能更优越.派生表与其他表一样出现在查询的FROM子句中 select * from (select * from athors) temp temp 就是派生表 派生出来的表必须要是一个有效的表.因此,它必须遵守以下几条规则: 1. 所有列必须要有名称 2. 列名称必须是要唯一 3. 不允许使用O