首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

请教SQL Server 中是否有类似ORACLE 中分区函数patition by 的机能

2012-01-18 
请问SQL Server 中是否有类似ORACLE 中分区函数patition by 的机能现在有两个表article(文章) 和type(文章

请问SQL Server 中是否有类似ORACLE 中分区函数patition by 的机能
现在有两个表article(文章) 和type(文章分类) 表结构如下
article:
  1. id int(4) 
  2. name varchar2(10)
  3. context ntext(200)
  4. typeid int(4)
  5. dateandtime smalldatetime(4)
type:
1.id int(4)
2.name varchar(10)

两个表通过article.typeid = type.id关联。现在想用1条sql检索 article中每个分类的最新三条记录。
例如;
Article 
  Id name context typeid dateandtime
  1 test1 <long text> 1 2008/03/24 18:00:00
  2 test2 <long text> 1 2008/03/24 18:01:00
  3 test3 <long text> 2 2008/03/24 18:00:00
  4 test4 <long text> 2 2008/03/24 18:02:00
  5 test5 <long text> 2 2008/03/24 18:03:00
  6 test6 <long text> 2 2008/03/24 18:04:00
Type
  Id name
1国际新闻
2国内新闻

那么我需要的检索结果是
Test6 <long text> 国内新闻 2008/03/24 18:04:00
Test5 <long text> 国内新闻 2008/03/24 18:03:00
Test4 <long text> 国内新闻 2008/03/24 18:02:00
Test2 <long text> 国内新闻 2008/03/24 18:01:00
Test1 <long text> 国内新闻 2008/03/24 18:00:00

[解决办法]

SQL code
select a.name,a.context,b.name,a.dateandtime from article a, type cwhere a.id in (select top 3 id  from article b where a.typeid=b.typeid order by dateandtime desc)and  a.typeid=b.typeid
[解决办法]
SQL code
select m.name,m.context,n.name , m.dateandtime from(  select t.* from article t where dateandtime in (select top 3 dateandtime from article where typeid = t.typeid order by dateandtime desc) ) m , type nwhere m.typeid = t.id
[解决办法]
SQL code
create table article(id int,name varchar(10),context varchar(20),typeid int,dateandtime datetime)insert into article values(1 , 'test1', '<long text>', 1 , '2008/03/24 18:00:00') insert into article values(2 , 'test2', '<long text>', 1 , '2008/03/24 18:01:00') insert into article values(3 , 'test3', '<long text>', 2 , '2008/03/24 18:00:00') insert into article values(4 , 'test4', '<long text>', 2 , '2008/03/24 18:02:00') insert into article values(5 , 'test5', '<long text>', 2 , '2008/03/24 18:03:00') insert into article values(6 , 'test6', '<long text>', 2 , '2008/03/24 18:04:00')create table type(Id int , name varchar(10))insert into type values(1 ,'国际新闻') insert into type values(2 ,'国内新闻')goselect m.name,m.context,n.name , m.dateandtime from(  select t.* from article t where dateandtime in (select top 3 dateandtime from article where typeid = t.typeid order by dateandtime desc) ) m , type nwhere m.typeid = n.iddrop table article, type/*name       context              name       dateandtime                                            ---------- -------------------- ---------- ------------------------------------------------------ test1      <long text>          国际新闻       2008-03-24 18:00:00.000test2      <long text>          国际新闻       2008-03-24 18:01:00.000test4      <long text>          国内新闻       2008-03-24 18:02:00.000test5      <long text>          国内新闻       2008-03-24 18:03:00.000test6      <long text>          国内新闻       2008-03-24 18:04:00.000(所影响的行数为 5 行)*/
[解决办法]
sql2005

SQL code
select row_number() over (partition by a order by b)as row ,*from(select 'a' a,'b' b union select 'a','c' union select 'b','a')a/*row                  a    b-------------------- ---- ----1                    a    b2                    a    c1                    b    a(3 行受影响)*/ 


[解决办法]
sql 2005的相关函数.

SQL code
ROW_NUMBER、RANK、DENSE_RANK的用法(爱新觉罗.毓华  2007-12-16  广东深圳)SQL Server 2005 引入几个新的排序(排名)函数,如ROW_NUMBER、RANK、DENSE_RANK等。这些新函数使您可以有效地分析数据以及向查询的结果行提供排序值。 --------------------------------------ROW_NUMBER()说明:返回结果集分区内行的序列号,每个分区的第一行从 1 开始。语法:ROW_NUMBER () OVER ( [ <partition_by_clause> ] <order_by_clause> ) 。备注:ORDER BY 子句可确定在特定分区中为行分配唯一 ROW_NUMBER 的顺序。参数:<partition_by_clause> :将 FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。       <order_by_clause>:确定将 ROW_NUMBER 值分配给分区中的行的顺序。返回类型:bigint 。示例:/*以下示例将根据年初至今的销售额,返回 AdventureWorks 中销售人员的 ROW_NUMBER。*/USE AdventureWorksGOSELECT c.FirstName, c.LastName, ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS 'Row Number', s.SalesYTD, a.PostalCodeFROM Sales.SalesPerson s JOIN Person.Contact c on s.SalesPersonID = c.ContactIDJOIN Person.Address a ON a.AddressID = c.ContactIDWHERE TerritoryID IS NOT NULL AND SalesYTD <> 0/*FirstName  LastName    Row Number  SalesYTD      PostalCode---------  ----------  ----------  ------------  ----------------------------Shelley    Dyck        1           5200475.2313  98027Gail       Erickson    2           5015682.3752  98055Maciej     Dusza       3           4557045.0459  98027Linda      Ecoffey     4           3857163.6332  98027Mark       Erickson    5           3827950.238   98055Terry      Eminhizer   6           3587378.4257  98055Michael    Emanuel     7           3189356.2465  98055Jauna      Elson       8           3018725.4858  98055Carol      Elliott     9           2811012.7151  98027Janeth     Esteves     10          2241204.0424  98055Martha     Espinoza    11          1931620.1835  98055Carla      Eldridge    12          1764938.9859  98027Twanna     Evans       13          1758385.926   98055(13 行受影响)*/ /*以下示例将返回行号为 50 到 60(含)的行,并以 OrderDate 排序。*/ USE AdventureWorks;GOWITH OrderedOrders AS(SELECT SalesOrderID, OrderDate,ROW_NUMBER() OVER (order by OrderDate)as RowNumberFROM Sales.SalesOrderHeader ) SELECT * FROM OrderedOrders WHERE RowNumber between 50 and 60;/*SalesOrderID OrderDate               RowNumber------------ ----------------------- --------------------43708        2001-07-03 00:00:00.000 5043709        2001-07-03 00:00:00.000 5143710        2001-07-03 00:00:00.000 5243711        2001-07-04 00:00:00.000 5343712        2001-07-04 00:00:00.000 5443713        2001-07-05 00:00:00.000 5543714        2001-07-05 00:00:00.000 5643715        2001-07-05 00:00:00.000 5743716        2001-07-05 00:00:00.000 5843717        2001-07-05 00:00:00.000 5943718        2001-07-06 00:00:00.000 60(11 行受影响)*/--------------------------RANK()说明:返回结果集的分区内每行的排名。行的排名是相关行之前的排名数加一。语法:RANK () OVER ( [ < partition_by_clause > ] < order_by_clause > )备注:如果两个或多个行与一个排名关联,则每个关联行将得到相同的排名。      例如,如果两位顶尖销售员具有同样的 SalesYTD 值,他们将并列第一。      由于已有两行排名在前,所以具有下一个最大 SalesYTD 的销售人员将排名第三。      因此,RANK 函数并不总返回连续整数。       用于整个查询的排序顺序决定了行在结果集中的显示顺序。这也隐含了行在每个分区中的排名。参数:< partition_by_clause > :将 FROM 子句生成的结果集划分为要应用 RANK 函数的分区。       < order_by_clause >:确定将 RANK 值应用于分区中的行时所基于的顺序。返回类型:bigint示例:/*以下示例按照数量对清单中的产品进行了排名。行集按 LocationID 分区,按 Quantity 排序。USE AdventureWorks;GOSELECT i.ProductID, p.Name, i.LocationID, i.Quantity, RANK() OVER (PARTITION BY i.LocationID order by i.Quantity) as RANKFROM Production.ProductInventory i JOIN Production.Product p ON i.ProductID = p.ProductIDORDER BY p.NameGO/*ProductID   Name                                               LocationID Quantity RANK----------- -------------------------------------------------- ---------- -------- --------------------1           Adjustable Race                                    6          324      711           Adjustable Race                                    1          408      781           Adjustable Race                                    50         353      1172           Bearing Ball                                       6          318      672           Bearing Ball                                       1          427      852           Bearing Ball                                       50         364      1223           BB Ball Bearing                                    50         324      1063           BB Ball Bearing                                    1          585      1103           BB Ball Bearing                                    6          443      1154           Headset Ball Bearings                              1          512      994           Headset Ball Bearings                              6          422      1084           Headset Ball Bearings                              50         388      140316         Blade                                              10         388      33......(1069 行受影响)*/  ------------------------------------------------- 


[解决办法]

SQL code
DENSE_RANK()说明:返回结果集分区中行的排名,在排名中没有任何间断。行的排名等于所讨论行之前的所有排名数加一。语法:DENSE_RANK () OVER ( [ < partition_by_clause > ] < order_by_clause > )备注:如果有两个或多个行受同一个分区中排名的约束,则每个约束行将接收相同的排名。      例如,如果两位顶尖销售员具有相同的 SalesYTD 值,则他们将并列第一。      接下来 SalesYTD 最高的销售人员排名第二。该排名等于该行之前的所有行数加一。      因此,DENSE_RANK 函数返回的数字没有间断,并且始终具有连续的排名。       整个查询所用的排序顺序确定了各行在结果中的显示顺序。这说明排名第一的行可以不是分区中的第一行。参数:< partition_by_clause > :将 FROM 子句所生成的结果集划分为数个将应用 DENSE_RANK 函数的分区。       < order_by_clause >:确定将 DENSE_RANK 值应用于分区中各行的顺序。返回类型:bigint示例:/*以下示例返回各位置上产品数量的 DENSE_RANK。 */USE AdventureWorks;GOSELECT  i.ProductID, p.Name, i.LocationID, i.Quantity, DENSE_RANK() OVER (PARTITION BY i.LocationID order by i.Quantity) as DENSE_RANKFROM Production.ProductInventory i JOIN Production.Product p ON i.ProductID = p.ProductIDORDER BY Name;GO/*ProductID   Name                                               LocationID Quantity DENSE_RANK----------- -------------------------------------------------- ---------- -------- --------------------1           Adjustable Race                                    1          408      571           Adjustable Race                                    6          324      521           Adjustable Race                                    50         353      82879         All-Purpose Bike Stand                             7          144      34712         AWC Logo Cap                                       7          288      383           BB Ball Bearing                                    50         324      743           BB Ball Bearing                                    6          443      813           BB Ball Bearing                                    1          585      82*/-------------------------------------------------------------------将上面三个函数放在一起计算,更能明显看出各个函数的功能。CREATE TABLE rankorder(orderid INT,qty INT)INSERT rankorder VALUES(30001,10)INSERT rankorder VALUES(10001,10)INSERT rankorder VALUES(10006,10)INSERT rankorder VALUES(40005,10)INSERT rankorder VALUES(30003,15)INSERT rankorder VALUES(30004,20)INSERT rankorder VALUES(20002,20)INSERT rankorder VALUES(20001,20)INSERT rankorder VALUES(10005,30)INSERT rankorder VALUES(30007,30)INSERT rankorder VALUES(40001,40)INSERT rankorder VALUES(30007,30)GO--对一个列qty进行的排序SELECT orderid,qty,       ROW_NUMBER() OVER(ORDER BY qty) AS rownumber,       RANK()       OVER(ORDER BY qty) AS rank,       DENSE_RANK() OVER(ORDER BY qty) AS denserankFROM rankorderORDER BY qty/*orderid     qty         rownumber            rank                 denserank----------- ----------- -------------------- -------------------- --------------------30001       10          1                    1                    110001       10          2                    1                    110006       10          3                    1                    140005       10          4                    1                    130003       15          5                    5                    230004       20          6                    6                    320002       20          7                    6                    320001       20          8                    6                    310005       30          9                    9                    430007       30          10                   9                    430007       30          11                   9                    440001       40          12                   12                   5(12 行受影响)*/ --对两个列qty,orderid进行的排序SELECT orderid,qty,       ROW_NUMBER() OVER(ORDER BY qty,orderid) AS rownumber,       RANK()       OVER(ORDER BY qty,orderid) AS rank,       DENSE_RANK() OVER(ORDER BY qty,orderid) AS denserankFROM rankorderORDER BY qty,orderiddrop table rankorder/*orderid     qty         rownumber            rank                 denserank----------- ----------- -------------------- -------------------- --------------------10001       10          1                    1                    110006       10          2                    2                    230001       10          3                    3                    340005       10          4                    4                    430003       15          5                    5                    520001       20          6                    6                    620002       20          7                    7                    730004       20          8                    8                    810005       30          9                    9                    930007       30          10                   10                   1030007       30          11                   10                   1040001       40          12                   12                   11(12 行受影响)*/ 

热点排行