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

从这里下载文件employees.txt,customers.txt,orders.txt

参考文章:http://www.cnblogs.com/wwan/archive/2011/02/24/1964279.html

使用package导入数据:http://www.cnblogs.com/tylerdonet/archive/2011/04/17/2017471.html

简单的聚合

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

  • 第一种写法,我们可以写成这样

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

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

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

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

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

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

  • 第四种写法,with出场了
    1with c as(
    2select YEAR(orderdate) orderyear, custid from sales.orders)
    3select orderyear,COUNT(distinct(custid)) numCusts from c group by orderyear
    4go

    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

引用至: http://www.cnblogs.com/tylerdonet/archive/2011/04/18/2020225.html

CREATE TABLE #tempTotalCBM
( Appointid int,
  TotalCBM NUMERIC
)

INSERT INTO #tempTotalCBM (Appointid,TotalCBM)
SELECT H.APPOINTID,
CAST(( CASE H.TruckerConfirm WHEN 'D' THEN SUM(D.DELIVERYCBM) ELSE SUM(D.CBM) END ) AS NUMERIC) AS TotalCBM
FROM
(
    SELECT APPOINTID , TruckerConfirm
    FROM CCC_TAHEADER
    WHERE
    DATEDIFF(D,RECEIVEDATE,'2010-10-01') <= 0
    AND DATEDIFF(D,RECEIVEDATE,GETDATE()) >= 0
) H
INNER JOIN CCC_TADETAIL D
ON D.APPOINTID = H.APPOINTID
GROUP BY H.APPOINTID,H.TruckerConfirm

SELECT M.APPOINTID,M.LOADTYPE,N.TotalCBM,
 L_TruckSize3T, L_TruckSize5T, L_TruckSize8T, L_TruckSize10T, L_TruckSize12T,
 Size20, Size40, Size40R, Size40HQ, Size45,ReceiveDate
FROM CCC_TAHEADER M
INNER JOIN
#tempTotalCBM N
ON M.APPOINTID = N.Appointid

-- SELECT * FROM #tempTotalCBM
DROP TABLE #tempTotalCBM

with c as (
SELECT H.APPOINTID,
CAST(( CASE H.TruckerConfirm WHEN 'D' THEN SUM(D.DELIVERYCBM) ELSE SUM(D.CBM) END ) AS NUMERIC) AS TotalCBM
FROM
(
    SELECT APPOINTID , TruckerConfirm
    FROM CCC_TAHEADER
    WHERE
    DATEDIFF(D,RECEIVEDATE,'2010-10-01') <= 0
    AND DATEDIFF(D,RECEIVEDATE,GETDATE()) >= 0
) H
INNER JOIN CCC_TADETAIL D
ON D.APPOINTID = H.APPOINTID
GROUP BY H.APPOINTID,H.TruckerConfirm
)

SELECT M.APPOINTID,M.LOADTYPE,c.TotalCBM,
 L_TruckSize3T, L_TruckSize5T, L_TruckSize8T, L_TruckSize10T, L_TruckSize12T,
 Size20, Size40, Size40R, Size40HQ, Size45,ReceiveDate
FROM CCC_TAHEADER M
INNER JOIN
c
ON M.APPOINTID = c.Appointid

转载于:https://www.cnblogs.com/zhangchenliang/archive/2011/04/19/2021036.html

SQL点滴9—使用with语句来写一个稍微复杂sql语句相关推荐

  1. sql语言和c语言比,SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比...

    今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章,自己添加了一些内容,做了简单的总结,这个语句还是第一次见到,学习了.我从简单到复杂地写, ...

  2. 使用with语句来写一个稍微复杂sql语句(经典,转载)

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

  3. mysql更新两表所有记录语句怎么写_mysql 一条sql语句update更新两个表

    mysql 一条sql语句update更新两个表 你写过一条sql语句来修改两个表的数据吗? UPDATE test.table1 t1,test.table2 t2 SET t1.aa='a',t1 ...

  4. mysql 删除一个字段语句怎么写_删除的sql语句怎么写

    1. 删除一个表的sql 语句怎么写啊 使用drop语句,drop table (需要删除表的名字). drop是删除整个表,delete是删除表的内容. drop语句的作用:删除内容和定义,释放空间 ...

  5. mysql更新多表sql语句怎么写_MySQL多表updatesql语句总结

    MySQL 多表 update 有几种不同的写法.假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是 MySQL 多表 update 有几种不同的写法. ...

  6. mysql修改数据的sql语句怎么写_MySQL数据库修改数据语句的简单用法

    1.insert语句 MySQL的insert语句有两种方式: INSERT INTO tablename() VALUES(列值); INSERT INTO tablename SET column ...

  7. php的修改数据库语句怎么写,php的数据库修改语句是什么

    php的数据库修改语句是UPDATE,用于更新数据库表中已存在的记录,语法为[UPDATE table_name SET column1=value, column2=value2,...WHERE ...

  8. java删除mysql 数据库语句怎么写_怎么用JAVA语句在Mysql中查询,添加,删除语句,说的详细点,谢谢!...

    展开全部 创建一个java project:对着project右键62616964757a686964616fe59b9ee7ad9431333264633564->属性 然后就 如图所示:导入 ...

  9. mysql删除数据库数据库语句怎么写_mysql数据库的删除语句怎么写

    我就废话不多说了,大家还是直接看代码吧~create or replace function aa1(a1 integer[],a2 bigint) returns void AS $$declare ...

最新文章

  1. 《统一沟通-微软-实战》-5-部署-SharePoint Server 2010
  2. A股光刻胶飙涨背后:仅一家可供应高端光刻胶
  3. 就算是戴上口罩,AI也知道你在说什么丨EMNLP 2020最佳论文
  4. bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash
  5. windows下钩子的使用
  6. Request爬取网站(seo.chinaz.com)百度权重的查询结果
  7. CodeForces 459C(构造题)
  8. python模拟火车订票系统_如何用python编写火车抢票助手
  9. python散点图如何设置外边框_如何绘制散点图的外围边框?
  10. 键盘录入一个正整数,把它的各个位上的数字倒着排列形成一个新的整数并输出。 例如:12345 数出54321 78760 输出6787(0省去)
  11. android系统特效详解和修改方法
  12. HTTPS 协议到底比 HTTP 协议多些什么?
  13. 离散数学——自动生成真值表、主合取范式
  14. Excel快速下拉填充序列至10000行
  15. 车辆网络安全ISO/SAE 21434解读(十)TARA分析
  16. 乐信、趣店同源“异路”
  17. 【Rust日报】 2019-06-01:知乎开源了Rust实现的搜索引擎 rucene
  18. 基于小样本量的水下图像识别
  19. Windows下 YOLOv5配置、部署、及遇到的问题
  20. 前端性能优化:启用 gzip

热门文章

  1. C#-WebForm-★★★JQuery知识——基础知识、选择器、事件★★★
  2. 超过屏幕长度字符省略
  3. powershell加win的dns服务器,解决网站负载均衡问题
  4. 最简单的moss单点登录第三方系统,有点非主流
  5. adb shell 书籍_开发必备---你应该知道的一些 ADB 命令
  6. java previous_java – 在枚举类型上实现`next`和`previous`的最好方法是什么?
  7. php symbol table,gdb方式遍历EG(symbol_table) 哈希表的key_PHP教程
  8. android 获取控件高度_安卓开发入门教程UI控件_ProgressBar
  9. 云服务器的主机名是否可以修改??
  10. java excel 操作方式_Java读写Excel基本操作