SQL点滴之使用with语句来写一个稍微复杂sql语句

数据库 SQL Server
偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊。看了一位博主的文章,自己添加了一些内容,做了简单的总结,这个语句还是第一次见到,学习了。我从简单到复杂地写,希望高手们不要见笑。

今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然***次接触,无知啊。看了一位博主的文章,自己添加了一些内容,做了简单的总结,这个语句还是***次见到,学习了。我从简单到复杂地写,希望高手们不要见笑。下面的sql语句设计到三个表,表的内容我用txt文件复制进去,这里不妨使用上一个随笔介绍的建立端到端的package的方法将这些表导入到数据库中,具体的就不说了。

简单的聚合

从orders表中选择各个年份共有共有多少客户订购了商品

***种写法,我们可以写成这样

  1. select YEAR(o.orderdate) orderyear,COUNT(distinct(custid)) numCusts  
  2. from Sales.Orders o  
  3. group by YEAR(o.orderdate)  
  4. go 

 要注意的是如果把group by YEAR(o.orderdata)换成group by orderyear就会出错,这里涉及到sql语句的执行顺序问题,有时间再了解一下          

第二种写法,

  1. select orderyear,COUNT(distinct(custid))numCusts  
  2. from (select YEAR(orderdate) as orderyear,custid from sales.orders) as D  
  3. group by orderyear  
  4. go  

在from语句中先得到orderyear,然后再select语句中就不会出现没有这个字段的错误了

第三种写法,

  1. select orderyear,COUNT(distinct(custid)) numCusts  
  2. from (select YEAR(orderdate),custid from sales.orders) as D(orderyear,custid)  
  3. group by orderyear  
  4. go  

在as D后面加上选择出的字段,是不是更加的清楚明了呢!

第四种写法,with出场了

  1. with c as(  
  2. select YEAR(orderdate) orderyear, custid from sales.orders)  
  3. select orderyear,COUNT(distinct(custid)) numCusts from c group by orderyear  
  4. go  

with可以使语句更加的经凑,下面是权威解释。  
    
指定临时命名的结果集,这些结果集称为公用表表达式 (CTE)。该表达式源自简单查询,并且在单条 SELECT、INSERT、UPDATE、MERGE 或 DELETE 语句的执行范围内定义。该子句也可用在 CREATE VIEW 语句中,作为该语句的 SELECT 定义语句的一部分。公用表表达式可以包括对自身的引用。这种表达式称为递归公用表达式。               
                                                ----MSDN

第五种写法,也可以借鉴第三种写法,这样使语句更加清楚明了,便于维护 

  1. with c(orderyear,custid) as(  
  2.  select YEAR(orderdate),custid from sales.orders)  
  3.  select orderyear,COUNT(distinct(custid)) numCusts from c group by c.orderyear  
  4.  go  


上面5中写法都得到相同的结果,如下图1:

 

图1

添加计算

现在要求要求计算出订单表中每年比上一年增加的客户数目,这个稍微复杂 

  1. with yearcount as(  
  2.   select YEAR(orderdate) orderyear,COUNT(distinct(custid)) numCusts from sales.orders group by YEAR(orderdate))  
  3.   select cur.orderyear curyear,cur.numCusts curNumCusts,prv.orderyear prvyear,prv.numCusts prvNumCusts,cur.numCusts-prv.numCusts growth  
  4.   from yearcount cur left join yearcount prv on cur.orderyear=prv.orderyear+1  
  5.  go  

这里两次使用到with结果集。查询得到的结果如下图2

图2

复杂的计算

查找客户id,这些客户和所有来自美国的雇员至少有一笔交易记录,查询语句如下

  1. with TheseEmployees as(  
  2. select empid from hr.employees where country='USA'),  
  3. CharacteristicFunctions as(  
  4. select custid,  
  5.        case when custid in (select custid from sales.orders as o where o.empid=e.empid) then 1 else 0 end as charfun  
  6. from sales.customers as c cross join TheseEmployees as e)  
  7. select custid,min(charfun) from CharacteristicFunctions group by custid having min(charfun)=1  
  8. go  

这里嵌套with语句,第with语句查找美国雇员的id,第二个语句使用这个结果和拥有客户的客户id和拥有关系标识做笛卡尔积运算。***从这个笛卡尔积中通过标识找到最终的custid。

结果如下图3

图3

这里只有简单地介绍,没有深入,高手们不要见笑啊。

 

【编辑推荐】

  1. SQL点滴之使用attach功能出现错误及解决方法
  2. SQL点滴之一个简单的字符串分割函数
  3. SQL点滴之重置win7登录密码对SQL登录的影响
  4. SQL点滴之SSIS中的事务处理
责任编辑:艾婧 来源: 博客园
相关推荐

2011-08-02 13:04:40

SQL Server

2011-09-09 10:10:13

SQL数据库点滴

2011-04-20 11:11:33

SQLSET QUOTED_

2011-04-28 09:49:56

SQLwith子查询

2011-10-09 16:40:50

T-SQL

2018-11-05 14:54:18

MySQLSQL语句数据库

2010-09-06 10:38:25

SQL Server语句

2016-09-28 17:34:27

JavaScriptvueWeb

2010-09-26 10:08:43

sql条件语句

2010-11-11 11:37:22

SQL SELECT语

2010-11-09 15:30:01

Sql server时

2010-09-25 11:02:33

SQL主键

2010-09-17 16:53:14

SQL中CREATE

2010-09-03 13:21:01

SQL删除

2011-06-23 14:00:51

SQL点滴

2009-09-07 16:25:14

Linq To SQL

2011-05-11 09:49:32

线程等待SQL Server

2021-04-08 09:49:49

MySQL索引数据库

2023-03-30 09:10:06

SQLSELECTFROM

2010-09-03 14:39:15

SQLSELECT语句
点赞
收藏

51CTO技术栈公众号