SQL Server:跨分区

SQL Server:跨分区,sql,sql-server,sql-server-2012,window-functions,Sql,Sql Server,Sql Server 2012,Window Functions,我正在尝试使用函数分区来生成结果,不幸的是,我正在处理没有主键的其他表设计,并且我无法添加我知道的一个 我的示例代码如下 CREATE TABLE mytable (OrderNo varchar(20), TaskNo int, Hours Decimal(2)) insert into mytable values ('GNR68003327','0001',1) insert into mytable values ('GNR68003327','0002',2) insert int

我正在尝试使用函数分区来生成结果,不幸的是,我正在处理没有主键的其他表设计,并且我无法添加我知道的一个

我的示例代码如下

CREATE TABLE mytable  (OrderNo varchar(20), TaskNo int, Hours Decimal(2))

insert into mytable values ('GNR68003327','0001',1)
insert into mytable values ('GNR68003327','0002',2)
insert into mytable values ('GNR68003327','0002',2)
insert into mytable values ('GNR68003327','0002',2)
insert into mytable values ('GNR68003327','0003',0)
insert into mytable values ('GNR68003327','0004',0)
insert into mytable values ('GNR68003327','0005',0)
insert into mytable values ('GNR68003327','0006',0)
insert into mytable values ('GNR68003327','0007',4)
insert into mytable values ('GNR68003327','0007',4)
insert into mytable values ('GNR68003327','0007',4)
insert into mytable values ('GNR68003327','0007',4)
我知道我可以使用distinct来获得以下结果,但是在这个例子中,我会更好地使用Partition,因为这只是我试图做的事情的一个例子,所以还有更多的事情要做

我要做的是在每次任务时返回小时列的第一个值。无更改,因此结果应该是

OrderNo     TaskNo  Hours 
GRN68003327 0001    1
GRN68003327 0002    2
GRN68003327 0003    0
GRN68003327 0004    0
GRN68003327 0005    0
GRN68003327 0006    0
GRN68003327 0007    4
我认为应该是这样的,但我就是不能得到所需的结果

SELECT 
    OrderNo, TaskNo, 
    First_Value(Hours) OVER (PARTITION BY OrderNo ORDER BY TaskNo) 
FROM 
    mytable
如果有人能帮忙,我将不胜感激

谢谢Phil

您必须按TaskNo和OrderNo进行分区才能得到想要的结果。由于您没有任何有意义的方法对这些分区中的行进行排序,因此您可以按TaskNo进行排序,但不能保证每次都会得到相同的第一条记录,而不需要某种顺序指示器:

SELECT OrderNo, 
       TaskNo, 
       First_Value(Hours) OVER (PARTITION BY OrderNo , TaskNo ORDER BY TaskNo) 
FROM mytable
您将使用行号:


注意这个??在查询中。SQL表表示无序集。集合中没有第一行或最后一行。您需要一个列来指定顺序。无论该列是什么,都将其用于???。

我假设您使用的是SQL 2012,因为您使用的是第一个值函数?如果是这样的话,那么SQL 2008标签就不适用了。嗨,斯坦利,是的,我正在使用SQL Server 2012,谢谢PHi Gordon,谢谢你的回复,非常感谢你的回答。p也感谢答案D
select t.*
from (select t.*,
             row_number() over (partition by orderno, taskno order by ??) as seqnum
      from mytable t
     ) t
where seqnum = 1;