sqlserver2005中TSql新功能


新添加的查询:CTE

WITH DirReps (Manager, DirectReports) AS
(
    SELECT ManagerID, COUNT(*) AS DirectReports
    FROM HumanResources.Employee
    GROUP BY ManagerID
)
SELECT AVG(DirectReports) AS [Average Number of Direct Reports]
FROM DirReps
WHERE DirectReports>= 2 ;
GO

  Row_number 取得行号,主要运用于排序; 返回bigint

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (order by OrderDate)as RowNumber
FROM Sales.SalesOrderHeader
)
SELECT *
FROM OrderedOrders
WHERE RowNumber between 50 and 60;

RANK ( ) 返回结果集的分区内每行的排名。行的排名是相关行之前的排名数加一
USE AdventureWorks;
GO
SELECT i.ProductID, p.Name, i.LocationID, i.Quantity,
RANK() OVER (PARTITION BY i.LocationID order by i.Quantity) as RANK
FROM Production.ProductInventory i JOIN Production.Product p
ON i.ProductID = p.ProductID
ORDER BY p.Name
GO


使用 APPLY
APPLY 运算符的左操作数和右操作数都是表表达式。这些操作数之间的主要区别是,
right_table_source 可以使用表值函数,从 left_table_source 获取一个列作为函数的参数之一。
left_table_source 可以包括表值函数,但不能以来自 right_table_source 的列作为参数


使用 APPLY
以下示例假定数据库中存在具有如下架构的以下表:

Departments: DeptID, DivisionID, DeptName, DeptMgrID


EmpMgr: MgrID, EmpID


Employees: EmpID, EmpLastName, EmpFirstName, EmpSalary

inner join区别在不能以来自 left_table_source 的列作为参数
还有一个表值函数(GetReports(MgrID))可以返回指定的 MgrID 直接或间接领导的所有员工的列表(EmpID、EmpLastName、EmpSalary)。

该示例使用 APPLY 返回所有部门和部门中的所有员工。如果某个部门没有任何员工,则不返回该部门的任何行。

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d CROSS APPLY dbo.GetReports(d.DeptMgrID) ;
相当于
 SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d inner join dbo.GetReports() e on d.DeptMgrID=e.mgrid

如果您希望查询为那些没有员工的部门生成行(为 EmpID、EmpLastName 和 EmpSalary 列生成空值),请使用 OUTER APPLY。

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d OUTER APPLY dbo.GetReports(d.DeptMgrID) ;
 

使用 PIVOT 和 UNPIVOT
USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
([164], [198], [223], [231], [233])
) AS pvt
ORDER BY VendorID
 

以下为部分结果集:

VendorID    Emp1        Emp2        Emp3        Emp4        Emp5
1           4           3           5           4           4
2           4           1           5           5           5
3           4           3           5           4           4
4           4           2           5           5           4
5           5           1           5           5           5
 
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int)
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4)
INSERT INTO pvt VALUES (2,4,1,5,5,5)
INSERT INTO pvt VALUES (3,4,3,5,4,4)
INSERT INTO pvt VALUES (4,4,2,5,5,4)
INSERT INTO pvt VALUES (5,5,1,5,5,5)
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM
   (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
   FROM pvt) p
UNPIVOT
   (Orders FOR Employee IN
      (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt
GO
 

以下为部分结果集:

VendorID   Employee   Orders
1      Emp1         4
1      Emp2         3
1      Emp3         5
1      Emp4         4

 

SQL Server 2005:数据类型最大值varchar(max)

交集函数:

SELECT * FROM A INTERSECT SELECT * FROM B

go
CREATE function uf_splitstring
(
@str varchar(8000) --要分拆的字符串
,@spli varchar(10) --字符串分隔符
)
returns @retab table(istr varchar(8000))
as
begin
 declare @i     int
 declare @splen int
 select @splen=len(@spli),@i=charindex(@spli,@str)
 while @i > 0
 begin
  insert into @retab
  values(left(@str,@i-1))
  select @str=substring(@str,@i+@splen,8000)
  select @i=charindex(@spli,@str)
 end
 if @str<>'' insert into @retab values(@str)
 return
end
GO
if exists(select 1 from uf_splitstring('001,002,003',',')t,uf_splitstring('002,004',',')t1 where t.istr=t1.istr)
print '1'
else
print '0'

例子:

DECLARE @T TABLE(ID INT,ParentId INT,Rank INT,StartDate DATETIME)
INSERT INTO @T SELECT 1,0,0,'2006-5-1'
UNION ALL SELECT 2,1,1,'2006-5-2'
UNION ALL SELECT 3,1,1,'2006-5-3'
UNION ALL SELECT 4,2,2,'2006-5-4'
UNION ALL SELECT 5,4,3,'2006-5-5'
UNION ALL SELECT 6,3,2,'2006-5-4';
DECLARE @TIME DATETIME
SET @TIME='2006-5-4';
WITH CTE_T(Id,ParentId,Rank,StartDate)
AS
(
SELECT Id,ParentId,Rank,StartDate
FROM @T
WHERE StartDate=@TIME
UNION ALL
SELECT A.Id,A.ParentId,A.Rank,A.StartDate
FROM @T A, CTE_T B
WHERE A.ID=B.ParentId
)
SELECT DISTINCT *,Tag=CASE WHEN StartDate>=@TIME THEN 1 ELSE 0 END
FROM CTE_T
go
---显示所有下级
WITH CTE_T(menuId,menuname)
 AS
 (
 SELECT menuid,menuname
 FROM _sysmenu
 WHERE parentmenu=0
 UNION all
 SELECT A.menuId,A.menuname
 FROM _sysmenu A,CTE_T B
 WHERE A.parentmenu=B.menuId
 )
 
 SELECT * FROM CTE_T 

go

---显示所有上级

WITH CTE_T(parentmenu,menuname)
 AS
 (
 SELECT parentmenu,menuname
 FROM _sysmenu
 WHERE menuid=2095
 UNION all
 SELECT A.parentmenu,A.menuname
 FROM _sysmenu A,CTE_T B
 WHERE A.menuid=B.parentmenu
 )
 
 SELECT * FROM CTE_T 


go

例子2.

create table table1(name varchar(10),course varchar(20),grade int)
insert into table1(name,course,grade) select 'lying','maths','100'
union
select 'lying2','english','200'
union
select 'lying1','chinese','50'
go
Declare @cols nvarchar(max);
WITH CTECourse(Course)
As
(
Select Distinct Course From table1
)

Select @cols = IsNull(@cols + ',[','[') + Course + ']' From CTECourse

DECLARE @sql AS nvarchar(MAX)
SET @sql = N'SELECT *
FROM (SELECT [Name], [Course], [Grade]
      FROM table1) as Header
  PIVOT(SUM([Grade]) FOR [Course] IN(' + @cols + N')) AS Piv'
PRINT @sql -- for debugging
EXEC sp_executesql @sql
go
drop table table1
 

你可能感兴趣的:(sqlserver2005中TSql新功能)