SQLServer2005T-SQL查询学习笔记(1)

SELECT语句在逻辑上是SQL语句最后处理的最后一步,因此下面的查询将产生错误:
选择
年(订单)为orderyear,
计数(明显的CustomerID)作为numcusts
Dbo。订单
集团由OrderYear;

因为组以前做过的选择,orderyear柱在当时并未形成。



如果你想查询成功,你可以修改如下:
选择orderyear,计数(明显的CustomerID)作为numcusts
从(选择年(订单)为orderyear,CustomerID
从订单为D)。
集团由OrderYear;

还有一种非常特殊的写作方式:
选择orderyear,计数(明显的CustomerID)作为numcusts
从(选择年(订单),CustomerID
由dbo。订单)D(orderyear,CustomerID)
集团由OrderYear;

在作者看来,他非常喜欢它,因为它更清晰,更清晰,更容易维护。



在查询中使用参数定向来生成一批结果没有什么要说的。



嵌套查询从内部逻辑地执行。



多个引用,您的SQL语句在表中多次查询后可能包含多个连接。例如,如果您将每年的客户数与上一年的客户数进行比较,则必须有2个相同表的实例进行连接,这是不可避免的。



常用表表达式(CTE)

CTE在SQL2005中增加一个新表表示的类型。

它的定义如下:

与cte_name

作为



cte_query



outer_query_refferring to_cte_name;

注:因为关键词已列入标准T-SQL语言,CTE是为了区别起见声明最后补充道;作为一个停止。



CTE实例1(结果集别名)
与C

选择年(订单)为orderyear,CustomerID
从订单dbo。

选择orderyear,计数(明显的CustomerID)作为numcusts
从C
集团由OrderYear;



当然,作者自己有一个比较推荐的写作方法:
C(orderyear、CustomerID)为

选择年(订单),CustomerID
Dbo。订单

选择orderyear,计数(明显的CustomerID)作为numcusts
从C
集团由OrderYear;



CTE实例两(多目标)
C1为

选择年(订单)为orderyear,CustomerID
从订单dbo。
),
C2

选择orderyear,计数(明显的CustomerID)作为numcusts
从C1
集团通过orderyear

选择orderyear,numcusts
从C2
在numcusts > 70;



CTE实例三(多个引用)
YearlyCount

选择年(订单)为orderyear,
计数(明显的CustomerID)作为numcusts
从订单dbo。
集团的年(订单)

选择cur.orderyear,
cur.numcusts作为curnumcusts,prv.numcusts作为prvnumcusts,
cur.numcusts - prv.numcusts生长
从当前yearlycount
左外连接yearlycount病毒
在cur.orderyear = prv.orderyear + 1;



CTE实例四(修改后的数据)

1。动态组合的结果从客户表到新表customersdups:
如果object_id('dbo。customersdups)是无效的
dbo.customersdups表;


CrossCustomers

选择1作为C,C1 *。
从dbo.客户C1、C2客户为dbo。

选择row_number()在(按C)KeyCol,
公司名称、联系人姓名、ID、contacttitle,地址,
市,区,PostalCode,国家,电话,传真
为dbo.customersdups
从crosscustomers;




2。使用CTE去除数据只有保持keycol最大记录在相同的ID在customerdups形式。
WITH JustDups AS

SELECT * FROM dbo.customersdups C1
在KeyCol的<<
(选择最大(keycol)从dbo.customersdups C2
在c2.customerid = C1 CustomerID)。

删除从justdups;



CTE实例五(对象容器)

它提供了封装的能力,这有利于基于组件的编程。作者的另一个提醒是CTE不能直接嵌入,但可以通过封装CTE到对象容器中来嵌入,并从外部CTE查询数据。



作者还解释说,鉴于UDFs的热膨胀系数和使用是没有价值的。

有一个例子,如下所示:
创建视图dbo.vyearcnt
作为
YearCnt

选择年(订单)为orderyear,
计数(明显的CustomerID)作为numcusts
Dbo。订单
集团的年(订单)

SELECT * FROM yearcnt;



CTE实例六(递归CTE)

作者对SQL2005的新内容递归的一个例子,CTEs。

根据EmployeeID、员工的信息返回,所有下属的信息。返回的结果(基于empolyeeid和报告属性层级关系)包含以下字段,EmployeeID、、,firstName、lastName。



在这里,作者给出了最好的索引方法:
创建唯一索引idx_mgr_emp_ifname_ilname
上dbo.员工(、、EmployeeID)
包括(firstName、lastName);



作者的解释:该指标将由一个单一的查询使用(局部扫描)得到各经理直接下级。包括(fristname,姓)添加在这里,即覆盖柱。



小常识:包括索引吗

包括指数是SQL2005的新功能,包括索引的列不影响索引行的物理存储顺序,他们挂在索引行'作为一个挂件,挂这些挂件的目的是通过扫描一个指标得到这些额外的数据。



回到作者的例子,下面是递归代码:
EmpsCTE

选择FirstName、LastName EmployeeID、、、
从员工dbo。
其中EmployeeID = 5
联盟的所有

选择emp.employeeid,emp.reportsto,emp.firstname,emp.lastname
从empscte为经理
加入dbo.员工为EMP
在emp.reportsto = mgr.employeeid

SELECT * FROM empscte;



理解:递归CTE包含至少2的查询,和第一个查询类似于CTE体格构锚固,锚只返回一个有效的表和作为递归的锚,锚的例子显示,只返回一行EmployeeID = 5。第二查询然后用作为一个递归成员。这个递归结束查询下属的结果是零。



如果您担心递归会导致永久循环,则可以使用以下表达式:

作为与cte_name(cte_body)outer_query选项(maxrecursion N);

默认的n是100,当n=0时,没有限制。