2016-01-21 92 views
-1

我试图去掌握使用函数Partition生成结果,不幸的是我正在处理别人没有主键的表设计,我不能添加一个“可怕的我知道“SQL Server:分区

我的示例代码如下

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) 

我知道我可以只使用一个独特得到以下的结果,但在这种情况下,我将使用分区的更好,由于这是只是一个示例我正在尝试这么做,还有更多的事情要做。

我想要做的每TaskNo变化返回Hours列的第一个值,所以结果应该是

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 

如果有人可以帮助它将不胜感激。

感谢菲尔

+0

我假设你正在使用SQL 2012,因为你使用'First_Value'函数?如果是这样,那么SQL 2008标记不适用。 –

+0

嗨Stanley,是的,我使用SQL Server 2012,谢谢P – PJD

回答

1

你会使用row_number()

select t.* 
from (select t.*, 
      row_number() over (partition by orderno, taskno order by ??) as seqnum 
     from mytable t 
    ) t 
where seqnum = 1; 

请注意,在查询??。 SQL表格代表无序集合。一组中没有第一行或最后一行。您需要一个指定排序的列。无论那一列是什么,都可以用它作为??

+0

嗨戈登,感谢您的答复,这是非常感谢你的答案。 P – PJD

1

你必须TaskNoOrderNo分区得到你想要的结果。由于您没有任何有意义的方式来订购这些分区内的行,您只需订购TaskNo,但不能保证每次都会得到相同的“第一”记录,而不需要某种订购指示器:

SELECT OrderNo, 
     TaskNo, 
     First_Value(Hours) OVER (PARTITION BY OrderNo , TaskNo ORDER BY TaskNo) 
FROM mytable 
+0

也谢谢答案D – PJD