SqlServer 2005 T-SQL Query 学习笔记(1)
发布时间:2024-01-25 17:01:56
Select字句在逻辑上是SQL语句最后进行处理的最后一步,所以,以下查询会发生错误:
SELECT YEAR(OrderDate) AS OrderYear, COUNT(DISTINCT CustomerID) AS NumCustsFROM dbo.OrdersGROUP BY OrderYear;
因为group by是在Select之前进行的,那个时候orderYear这个列并没有形成。
如果要查询成功,可以像下面进行修改:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCustsFROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID FROM dbo.Orders) AS DGROUP BY OrderYear;
还有一种很特殊的写法:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCustsFROM (SELECT YEAR(OrderDate), CustomerID FROM dbo.Orders) AS D(OrderYear, CustomerID)GROUP BY OrderYear;
在作者眼里,他是非常喜欢这种写法的,因为更清晰,更明确,更便于维护。
在查询中使用参数定向产生一批结果,这个技巧没有什么好说的。
嵌套查询,在处理逻辑上是从里向外进行执行的。
多重引用,有可能你的SQL语句包含了多次从一个表进行查询后进行连接组合。比如你要比较每年的顾客数同先前年的顾客数的变化,所以你的查询就必须JOIN了2个相同的表的实例,这也是不可避免的。
Common Table Expressions (CTE)
CTE是在SQL2005新加入的一种表的表示类型。
它的定义如下:
WITH cte_name
AS
(
cte_query
)
outer_query_refferring to_cte_name;
注意:因为在标准的T-SQL语言中已经包含了WITH关键字,所以为了区分,CTE在语句的结尾加上了“;”作为停止符。
CTE实例一(结果集别名)
WITH C AS( SELECT YEAR(OrderDate) AS OrderYear, CustomerID FROM dbo.Orders)SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCustsFROM CGROUP BY OrderYear;
当然,作者本人有更推荐的写法:
WITH C(OrderYear, CustomerID) AS( SELECT YEAR(OrderDate), CustomerID FROM dbo.Orders)SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCustsFROM CGROUP BY OrderYear;
CTE实例二(多重CTEs)
WITH C1 AS( SELECT YEAR(OrderDate) AS OrderYear, CustomerID FROM dbo.Orders),C2 AS( SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM C1 GROUP BY OrderYear)SELECT OrderYear, NumCustsFROM C2WHERE NumCusts > 70;
CTE实例三(多重引用)
WITH YearlyCount AS( SELECT YEAR(OrderDate) AS OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM dbo.Orders GROUP BY YEAR(OrderDate))SELECT Cur.OrderYear, Cur.NumCusts AS CurNumCusts, Prv.NumCusts AS PrvNumCusts, Cur.NumCusts - Prv.NumCusts AS GrowthFROM YearlyCount AS Cur LEFT OUTER JOIN YearlyCount AS Prv ON Cur.OrderYear = Prv.OrderYear + 1;
CTE实例四(修改数据)
1.把从customer表查询出来的结果,动态的组装进新表CustomersDups里:
IF OBJECT_ID('dbo.CustomersDups') IS NOT NULL DROP TABLE dbo.CustomersDups;GOWITH CrossCustomers AS( SELECT 1 AS c, C1.* FROM dbo.Customers AS C1, dbo.Customers AS C2)SELECT ROW_NUMBER() OVER(ORDER BY c) AS KeyCol, CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, FaxINTO dbo.CustomersDupsFROM CrossCustomers;
2.使用CTE移除数据,只保留CustomerDups表里同一CustomerID里KeyCol为最大的记录。
WITH JustDups AS( SELECT * FROM dbo.CustomersDups AS C1 WHERE KeyCol < (SELECT MAX(KeyCol) FROM dbo.CustomersDups AS C2 WHERE C2.CustomerID = C1.CustomerID))DELETE FROM JustDups;
CTE实例五(对象容器)
即提供了封装的能力,有利于组件化的编程。作者额外的提醒,CTE无法直接内嵌,但是可以通过把CTE封装进一个对象容器里并从一个外部的CTE里对这容器的数据进行查询而实现内嵌。
作者也说明了,使用CTEs在VIEW和UDFs里是没有什么价值的。
有个例子,如下:
CREATE VIEW dbo.VYearCntASWITH YearCnt AS( SELECT YEAR(OrderDate) AS OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts FROM dbo.Orders GROUP BY YEAR(OrderDate))SELECT * FROM YearCnt;
CTE实例六(CTEs的递归)
作者给了一个例子,来讲述这个在SQL2005的新内容,CTEs的递归。
根据employeeId,返回此员工的信息,并包含所有下级员工的信息。(等级关系基于empolyeeId和reportsTo的属性)所返回的结果包含下列字段,employeeId,reportsTo,FirstName,LastName。
作者在这里,给予了一个最佳的索引方式:
CREATE UNIQUE INDEX idx_mgr_emp_ifname_ilname ON dbo.Employees(ReportsTo, EmployeeID) INCLUDE(FirstName, LastName);
作者的解释: 这个索引将通过一个单独的查询(局部扫描)来取得每个经理的直接下级。Include(FristName,LastName)加在这里,即是覆盖列。
小知识:什么Include索引?
Include索引是SQL2005的新功能。Include索引的列并不影响索引行的物理存储顺序,他们作为一个挂件‘挂在'索引行上。挂这些‘挂件'的目的在于,只需要扫描一把索引就获得了这些附加数据。
回到作者的例子上,下面是递归的代码:
WITH EmpsCTE AS( SELECT EmployeeID, ReportsTo, FirstName, LastName FROM dbo.Employees WHERE EmployeeID = 5 UNION ALL SELECT EMP.EmployeeID, EMP.ReportsTo, EMP.FirstName, EMP.LastName FROM EmpsCTE AS MGR JOIN dbo.Employees AS EMP ON EMP.ReportsTo = MGR.EmployeeID)SELECT * FROM EmpsCTE;
理解:一个递归的CTE包含了至少2个查询,第一个查询在CTE的身体里类似于一格锚点。这个锚点仅仅返回一个有效的表,并作为递归的一个锚。从上的例子看出来,锚点仅仅返回了一个employeeID = 5 的一行。然后的第2个查询是作为递归成员。当查询到下属成员的结果为空时,此递归结束。
如果你担心递归会造成永久循环,你可以使用下面的表达:
WITH cte_name AS (cte_body) outer_query OPTION (MAXRECURSION n);
默认的n为100,当n=0时,无限制。
猜你喜欢
- 本文实例讲述了python获取图片颜色信息的方法。分享给大家供大家参考。具体分析如下:python的pil模块可以从图片获得图片每个像素点的
- python是一个很有趣的语言,可以在命令行窗口运行。python中有很多功能强大的模块,这篇经验告诉你,如何使用python的pygal模
- 平时我们在使用MySQL数据库的时候经常会因为操作失误造成数据丢失,MySQL数据库备份可以帮助我们避免由于各种原因造成的数据丢失或着数据库
- 直接奔入主题看下面pywebio程序,实现了Python的简陋在线编辑器from pywebio.input import *from py
- tensor计算三通道均值今天用pytorch处理图像时,涉及到了计算均值的问题,整理一下解决思路。第一种思路tensor转换为numpy再
- python绘制横向水平柱状条形图Bar,供大家参考,具体内容如下import matplotlibimport randomimport
- 在使用SQL Server 的过程,中由于经常需要从多个不同地点将数据集中起来或向多个地点复制数据,所以数据的导出,导入是极为常见的操作.我
- 有时一些网页对源码进行了加密,我们很难找到类似像“onselectstart="return false"”这样的代码,
- pandas删除部分数据后重新索引在使用pandas时,由于隔行读取删除了部分数据,导致删除数据后的索引不连续:原数据删除部分数据后在绑定p
- []*int是一个指向指针的切片,本质上是切片,只不过切片里面存放的元素是指针;*[]int是一个指向切片的指针,本质上是指针,可以用*来获
- 之前已经写过一篇关于Django外键的文章,但是当时并没有介绍如何根据外键对数据的操作,也就是如何通过主表查询子表或者通过子表查询主表的信息
- 什么是品牌的视觉传达品牌,这个熟悉而又陌生的名词,有时总会让人产生误解。品牌很广,广到一个意会颇深的战略发展理念;品牌很小,小到一个清晰可见
- 问题你想定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值。解决方案定义一个有可选参数的函数是非常简单的,直接在函数定义中给参
- 由于是从源码包安装的Mysql,所以系统中是没有红帽常用的servcie mysqld restart这个脚本只好手工重启有人建议Killa
- 本文实例为大家分享了python实现移动木板小游戏的具体代码,供大家参考,具体内容如下一、游戏简介本游戏是通过python编写的小游戏,给初
- 前言最近因为工作的需要,在写一些python脚本,总是使用print来打印信息感觉很low,所以抽空研究了一下python的logging库
- 本文实例讲述了Python面向对象之继承和多态用法。分享给大家供大家参考,具体如下:Python 类的继承和多态Python 类的继承在OO
- 简介:这里是利用了selenium+图片识别验证,来实现12306的模拟登录,中间也参考了好几个项目,实现了这个小demo,中间也遇到了很多
- 前言本文主要给大家介绍的是关于python对配置文件.ini增删改查操作的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的
- 字符串类型代码的执行字符串类型代码的执行函数有三个,都是Python的内置函数。eval()执行字符串类型的代码,并返回最终结果。exec(