原文:SQL点滴23—T-SQL中的除法

  

在T-SQL中没有除法运算,但是在T-SQL中可以实现类似除法的操作Divide。一般除法操作的结果一个列来自于被除关系表,剩下的来自除关系表。这里举一个例子来说明。假设如下有三个表:客户Customers,销售人员Employees,订单Orders,查询返回一些客户,要求这些客户和所有美国雇员都至少有一次交易记录。来看下面一个语句:

select custid from Sales.Customers as C
where not exists
(select * from HR.Employees as E
where country='USA'
and not exists
(select * from Sales.Orders as O
where O.custid = C.custid
and O.empid = E.empid))

  

语句返回23行,标明有23名客户,这些客户至少和每个美国雇员有一次交易记录。现在我们如果修改一下条件,问题要求还是一样的,我们把销售人员的国家修改成以色列Israel,看看以色列的销售人员是否能像美国雇员一样的强悍。

  

select custid from Sales.Customers as C
where not exists
(select * from HR.Employees as E
where country='Israel'
and not exists
(select * from Sales.Orders as O
where O.custid = C.custid
and O.empid = E.empid))

  

修改国家条件,这次我们查询得到的结果是91条记录,我们看看Customers这个表总共也就91条记录,很明显这个结果不对。我们使用语句来看看select * from Sales.Customers where country like '%Israel%',查询得到0条记录,就是说根本就没有以色列的雇员。因为没有来自以色列的雇员,所有雇员和该客户拥有至少一项交易记录这个条件对每个雇员都满足,这个是代数里面的空真现象。换句话说每个客户都和这个不存在的以色列雇员至少有一项交易记录。这个很像除法运算的一个规则:除数是0,商就是无限大

  
写上面的语句的时候,我们没有考虑如果Employee表中没有如果没有以色列的雇员怎么办。如果我们在问题中加上确实存在来自以色列的雇员就可以避免这个错误,只需要在条件中限定至少有一个以色列雇员存在于表Employee中就可以了。这个就像除法中的非0限定:除数不为0。语句如下:

  

select custid from Sales.Customers as C
where not exists
(select * from HR.Employees as E
where country='Israel'
and not exists
(select * from Sales.Orders as O
where O.custid = C.custid
and O.empid = E.empid))
and exists (select * from HR.Employees as E where country='Israel')

现在查询得到0条结果,这才是我们想要的。

  
在这个除法操作中有三个关系,a Divide by b Per c,a是被除数,b是除数,c是中介关系。假设a有属性A,b有属性B。在上面的语句中被除关系是Customers,除数关系是满足一定关系的Employee,中介关系是Orders。这里为了避免除数是0 的问题,使用第四个临时关系(select * from HR.Employees as E where country='Israel')。也可以使用另外一种方法来限定至少有一名以色列的销售人员和所有顾客至少有一次交易记录。如下:
a,找到美国雇员的id:select empid from HR.Employees where country='USA',这个语句找到的是(1,2,3,4,8)。
b,找到美国雇员的数量:select COUNT(*) from HR.Employees where country='USA',很明显这个找到的结果是5。
c,根据雇员id查找交易记录表中的客户id,并按客户id分组,在分组中查找不重复的empid数目等于5的。

  

select custid
from Sales.Orders
where empid in (1,2,3,4,8) group by custid having count(distinct empid)=5

  

我们把上面两个查询还原上去,由于没有以色列的雇员,还是使用美国雇员:

select custid
from Sales.Orders
where empid in
(select empid from HR.Employees where country = N'USA')
group by custid
having count(distinct empid) = (select count(*) from HR.Employees where country = N'USA')

查询得到的结果是23条记录,符合我们的要求。

 

SQL点滴23—T-SQL中的除法的更多相关文章

  1. SQL点滴15—在SQL Server 2008中调用C#程序

    原文:SQL点滴15-在SQL Server 2008中调用C#程序 T-SQL的在执行普通的查询的时候是很高效的,但是在执行循环,判断这样的语句的时候效率就不那么的高了.这时可以借助CLR了,我们可 ...

  2. SQL点滴2—重温sql语句中的join操作

    原文:SQL点滴2-重温sql语句中的join操作 1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,R ...

  3. SQL点滴7—使用SQL Server的attach功能出现错误及解决方法

    原文:SQL点滴7-使用SQL Server的attach功能出现错误及解决方法 今天用SQL Server 2008的attach功能附加一个数据库,出了点问题,提示的错误是: Unable to ...

  4. Azure SQL Database (23) Azure SQL Database Dynamic Data Masking动态数据掩码

    <Windows Azure Platform 系列文章目录> 我们在使用关系型数据的时候,有时候希望: - 管理员admin,可以查看到所有的数据 - 普通用户,某些敏感字段,比如信用卡 ...

  5. SQL点滴17—使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识

    原文:SQL点滴17-使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识 在开发过程中会遇到需要弄清楚这个数据库什么时候建的,这个数据库中有多少表,这个存储过程长的什么样子等等信息 ...

  6. sql点滴42—mysql中的时间转换

    原文:sql点滴42-mysql中的时间转换 UNIX时间戳转换为日期用函数: FROM_UNIXTIME() select FROM_UNIXTIME(1156219870); 日期转换为UNIX时 ...

  7. sql点滴42—mysql中的数据结构

    原文:sql点滴42-mysql中的数据结构 MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数.许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小 ...

  8. SQL点滴19—T-SQL中的透视和逆透视

    原文:SQL点滴19-T-SQL中的透视和逆透视 透视 今天抽一点时间来看看透视和逆透视语句,简单的说就是行列转换.假设一个销售表中存放着产品号,产品折扣,产品价格三个列,每一种产品号可能有多种折扣, ...

  9. SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务

    原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...

随机推荐

  1. Python标准库09 当前进程信息 (部分os包)

    原文:Python标准库09 当前进程信息 (部分os包) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们在Linux的概念 ...

  2. socket抓取网页

    #include <iostream> #include <string> #include <netdb.h> #include <stdio.h> ...

  3. 【 D3.js 入门系列 --- 10.2 】 你可以拖动地图

    我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处.谢谢. 本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用 ...

  4. 使用newLISP由SMTPserver发送电子邮件

    直接使用的标准模块smtpx.lsp, smtp.lsp你可以不设置port,庭审后,没用. 以下是一个示例代码: #!/usr/bin/newlisp (set 'debug-flag true) ...

  5. ABP之动态WebAPI

    ABP之动态WebAPI ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 ...

  6. 记得12306货运系统“抢购空”编写插件--chrome交互式插件的各个部分

    --chrome交互式插件的各个部分 Chrome插件的基础知识就不多说了.随便找个新手教程就能够上手了,比如官方提供的Overview与Getting Started教程足够入门了:笔者也是现学现卖 ...

  7. typeof + instanceof+toString+constructor什么推理javascript数据类型

    一个.typeof JS这些变量是弱类型(这是弱类型)的,它可以不管用来存储数据的类型的. typeof 数据类型可用于检测给定的变量.可能的返回值: 1. 'undefined' --- 这个值没有 ...

  8. WebAPI客户端

    封装WebAPI客户端,附赠Nuget打包上传VS拓展工具 一.前言 上篇< WebAPI使用多个xml文件生成帮助文档 >有提到为什么会出现基于多个xml文件生成帮助文档的解决方案,因为 ...

  9. ASP.NET WebAPI从入门

    在新出的MVC4中,增加了WebAPI,用于提供REST风格的WebService,新生成的WebAPI项目和典型的MVC项目一样,包含主要的Models.Views.Controllers等文件夹和 ...

  10. ClassLoader—流程观察程序执行类加载-verbose:class

    当调试器,有时你需要看到程序加载的类.记忆的恢复情况.本地接口调用,等等..这时候就需要-verbose命令. 在myeclipse能够通过右键设置(例如以下).也能够在命令行输入java -verb ...