T-SQL with关键字
T-SQL with关键字
Select字句在逻辑上是SQL语句最后进行处理的最后一步,所以,以下查询会发生错误:
SELECT
YEAR(OrderDate) AS OrderYear,
COUNT(DISTINCT CustomerID) AS NumCusts
FROM dbo.Orders
GROUP BY OrderYear;
因为group by是在Select之前进行的,那个时候orderYear这个列并没有形成。
如果要查询成功,可以像下面进行修改:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID
FROM dbo.Orders) AS D
GROUP BY OrderYear;
还有一种很特殊的写法:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (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 NumCusts
FROM C
GROUP BY OrderYear;
当然,作者本人有更推荐的写法:
WITH C(OrderYear, CustomerID) AS
(
SELECT YEAR(OrderDate), CustomerID
FROM dbo.Orders
)
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM C
GROUP 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, NumCusts
FROM C2
WHERE 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 Growth
FROM 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;
GO
WITH 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, Fax
INTO dbo.CustomersDups
FROM 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.VYearCnt
AS
WITH 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时,无限制。
T-SQL with关键字的更多相关文章
- //sql过滤关键字
//sql过滤关键字 public static bool CheckKeyWord(string sWord) { //过滤关键字 string StrKeyWord = @"select ...
- SQL保留关键字不能用作表名
com.microsoft.sqlserver.jdbc.SQLServerException: 关键字 'User' 附近有语法错误. 一看就是SQL语句错误,发现控制台console上打印出来的S ...
- 单表:SQL语句关键字的执行顺序
表和数据: -- 创建表 CREATE TABLE `person` ( `id` ) NOT NULL AUTO_INCREMENT, `name` ) NOT NULL, `age` ) ', ` ...
- sql的关键字
整理一下sql的关键字,一直都在用,只是很少去整理,所以今天简单整理一下,主要是整理CRUD的一些关键字. 写在前面:sql 不区分大小写 select 简单查询语句 select columnNam ...
- mybatis plus 使用 SQL 保留字(关键字)
MybatisPlus:使用SQL保留字(关键字)的操作 必须要手动在 entity 的字段上加注解,否则最终会报错,因为 mybatis 或者 mybatis plus 不会自动处理
- SQL数据库关键字和列名冲突处理
在设计SQL数据库的时候可能由于考虑不全,使列名和数据库内关键字冲突,可能导致Query不能被正确识别,对列名要加[]处理.
- 容斥原理及SQL in关键字在EF中的应用
突然意识到文字的重要性,于是开始写了第一个篇博客,博客目的紧紧为记录,以便温故. 同时也希望抛砖能达到引玉的作用,欢迎各位来发表自己的感想与想法,以此达到相互学习促进! 背景: 在做百度地图电子围栏的 ...
- 【转】SQL 常用关键字释义和用法
转自: http://blog.csdn.net/iamwangch/article/details/8093933 下面 是 从网络上整理 出来的 SQL 关键字和 常用函数的 释义和简单用 ...
- SQL中关键字的执行顺序
作为一个SQL新手,看到每种不熟悉的关键字时已经够迷茫了,可往往见到的语句关键字顺序还是各种各样,太难理解了.网上搜索了两篇文章,总结一下: 关于Sql关键字SELECT FROM GROUP ORD ...
- SQL基础 关键字
SQL语言类型 数据定义:create/alter/drop table/trigger/index/function/存储过程/约束/…数据操纵:select/update/insert/delet ...
随机推荐
- Educational Codeforces Round 38 部分题解
D. Buy a Ticket 分析 建一个源点,连向所有结点,边的花费为那个结点的花费,图中原有的边花费翻倍,最后跑一遍最短路即可. code #include<bits/stdc++.h&g ...
- 【JAVAWEB学习笔记】26_Linux基础:简介安装、常用命令和JDK、Mysql、Tomcat的安装
Linux基础 学习目标 1.了解Linux的简介与安装 2.掌握Linux常用的命令 3.掌握Linux系统上JDK.Mysql.Tomcat的安装 一.Linux的简介 1.Linux的概述 Li ...
- 【BZOJ 3482】 3482: [COCI2013]hiperprostor (dij+凸包)
3482: [COCI2013]hiperprostor Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 277 Solved: 81 Descrip ...
- 看雪论坛 破解exe 看雪CTF2017第一题分析-『CrackMe』-看雪安全论坛
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 逆向 黑客 破解 学习 论坛 『CrackMe』 http://bbs.pediy.co ...
- WPF TreeGrid的一种简单实现
前几天,各种坑爹的情况,导致不得不自己去动手实现带层级关系的Grid.之后翻了翻书,貌似说msdn和codeproject上有这么个例子,叫做TreeListView.这里就简单说下自己的思路,也许有 ...
- 【2-SAT】HDU3622-Bomb Game
[题目大意] 给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围都不相交(可以相切) ...
- 20162327WJH四则运算第二周总结
学号 20162327 <程序设计与数据结构>四则运算第二次实验报告 1.需求分析 1.本周我们进行了四则运算的后续完善,因为学习的比较欠缺,所以我负责比较简单的部分,就是只包含一个运算符 ...
- Java的运行机制概括
这次随笔主要记录一下我对Java的平台无关性一些新的理解,以前只知道是Java是一门很容易跨平台的语言,正如 "Compile once, run anywhere" 这句话,也知 ...
- CDOJ 1292 卿学姐种花 暴力 分块 线段树
卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...
- Markdown 简明语法手册 - 作业
目录 Cmd Markdown 简明语法手册 1. 内容目录 2. 标签分类 3. 删除线 水平线--- 1. 斜体和粗体 2. 分级标题 标题1 标题2 标题3 3. 外链接 4. 无序列表 5. ...