TOP关键字

 select top  WITH TIES t.title,sum(s.qty)as totalSales from sales s
left join titles t on s.title_id=t.title_id
group by t.title
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关键字的后边。实例:

 select t.state,t.stor_name,sum(s.qty)as totalSales
from sales s join stores as t on s.stor_id=t.stor_id
group by t.state,t.stor_name
order by totalSales desc select top t.state,t.stor_name,sum(s.qty)as totalSales
from sales s join stores as t on s.stor_id=t.stor_id
group by t.state,t.stor_name
order by totalSales desc

派生表

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

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

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

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

 select * from (
select 'Blotchet-Halls' as weightClass , as lowBound , as highBound
union all
select 'DeFrance' as weightClass , as lowBound , as highBound
union all
select 'Green' as weightClass , as lowBound , as highBound
)as w
order by w.lowBound

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

连接

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

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

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

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

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

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

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

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

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

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

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

谓词

  BETWEEN

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

 select au_lname,au_fname from authors
where au_lname between 's' and 'zz'
order by au_lname

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

 Declare @au_id id
select @au_id=(select max(au_id) from titleauthor) select au_lname,au_fname from authors
where au_id between (select min(au_id) from titleauthor) and (ISNULL(@au_id,'zzzzzzzzzzzzz'))
order by au_lname

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

  LIKE

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

  %:表示匹配任意字符

  _:表示只匹配一个字符

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

  EXISTS

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

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

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

  在EXISTS中NULL值的处理

 select title from titles t
where EXISTS(--此时为true
select * from(
select *from sales
union all
select null,null,null,90,null,null
) s--通过union all插入了一条为null,qty为90的数据
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有一些特殊性。

 select Count(title) from titles t
where t.title_id in(select title_id from sales)--16条 select Count(title) from titles t
where t.title_id not in(select title_id from sales)--2条 select Count(title) from titles t
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

 select * from titles where title_id in
(
select title_id from (
select top 99999 title_id,count(*) as numberOrder from sales group by title_id order by numberOrder desc
)s
)

  

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

  1. SQL笔记-第七章,表连接

    SQL中使用JOIN 关键字来使用表连接.表连接有多种不同的类型,被主流数据库系统支持的有交叉连接(CROSS JOIN).内连接(INNER JOIN).外连接(OUTTER JOIN),另外在有的 ...

  2. SELECT中的多表连接

    MySQL多表连接查询 连接(join):将一张表中的行按照某个条件(连接条件)和另一张表中的行连接起来形成一个新行的过程. 根据连接查询返回的结果,分3类: 内连接(inner join) 外连接( ...

  3. 【SQL】IN、EXISTS和表连接三者的效率比较

    一. IN和EXISTS比较 在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行查询.此时就会用到IN和EXISTS. 例如:查询departments表中存在的部门的人数. 1. 使 ...

  4. [SQL Server]多次为 '派生表' 指定了列 'id'

    问题: 原因: 因为派生表oo中出现了两个同样的'ID'属性,所以会报[多次为 'o' 指定了列 'ID']的错误. 只需要把第二个星号替换成所需要的列名并把重复字段重命名就好了 解决方案:

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

    进行数据库测试时需要根据不同场景查询数据,以便验证发现的问题是否为脏数据引起的.记录一下最近常用的查询方法: 1. 查询表中重复数据(id不同,多个字段值相同) select P1.* from pr ...

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

    在实际工作中会用到多表联查,此时需要用到关键字JOIN 一.inner join(内连接) 至少有一个匹配时返回行,只返回两个表中连接字段相等的行 如: select * from ticket in ...

  7. MySQL学习之路6-数据表连接方式

    内连接 关键字: inner join  on 语句:select * from <a_table> inner join <b_table> on a.id = b.id ; ...

  8. SQL学习笔记三之MySQL表操作

    阅读目录 一 存储引擎介绍 二 表介绍 三 创建表 四 查看表结构 五 数据类型 六 表完整性约束 七 修改表ALTER TABLE 八 复制表 九 删除表 一 存储引擎介绍 存储引擎即表类型,mys ...

  9. SQL学习——SELECT INTO和INSERT INTO SELECT

    原文链接 SELECT INTO 作用 SELECT INTO 语句从一个表中复制数据,然后将数据插入到另一个新表中. SELECT INTO 语法 我们可以把所有的列都复制到新表中: SELECT ...

随机推荐

  1. matplotlib命令与格式:标题(title),标注(annotate),文字说明(text)

      1.title设置图像标题 (1)title常用参数 fontsize设置字体大小,默认12,可选参数 ['xx-small', 'x-small', 'small', 'medium', 'la ...

  2. 【特 性】Attribute

    1 AttributeUsage [AttributeUsageAttribute(AttributeTargets.All, AllowMultiple = true, Inherited = tr ...

  3. 洛谷——P1896 [SCOI2005]互不侵犯

    P1896 [SCOI2005]互不侵犯 状压DP入门题 状压DP一般需要与处理状态是否合法,节省时间 设定状态dp[i][j][k]表示第i行第j个状态选择国王数为k的方案数 $dp[i][j][n ...

  4. UVALive 3026(KMP算法)

    UVALive 3026     KMP中next[]数组的应用: 题意:给出一个字符串,问该字符串每个前缀首字母的位置和该前缀的周期. 思路:裸KMP直接上就是了: 设该字符串为str,str字符串 ...

  5. BZOJ 1602 USACO 2008 Oct. 牧场行走

    [题解] 要求出树上两点间的距离,树上的边有边权,本来应该是个LCA. 看他数据小,Xjb水过去了...其实也算是LCA吧,一个O(n)的LCA... #include<cstdio> # ...

  6. hdu2007 平方和与立方和【C++】

    平方和与立方和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  7. FOJ2250 不可能弹幕结界

    Problem 2250 不可能弹幕结界 Time Limit: 1000 mSec    Memory Limit : 65536 KB Problem Description 咲夜需要穿过一片弹幕 ...

  8. 清北学堂模拟赛d7t1 消失的数字

    题目描述 现在,我的手上有 n 个数字,分别是 a1; a2; a3; :::; an.我现在需要删除其中的 k 个数字.当然我不希望随随便便删除,我希望删除 k个数字之后,剩下的 n - k 个数中 ...

  9. [cogs736][网络流24题#13]星际转移[网络流,网络判定]

    将一个空间站分为天数个点,每次枚举天数,每增加一天就把对应天数的边连上,用网络流判定可行性,即-判断最大流是否不小于k,注意编号不要错位.通过此题,可见一些网络流题目需要用到网络判定方法,但虽然答案具 ...

  10. nyoj_17_单调递增最长子序列_201403121516

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4   输入 ...