简体   繁体   English

SQL Server:过度分区

[英]SQL Server : Over Partition

I am trying to get to grips with using the function Partition to generate results, unfortunately I am dealing with someone else table design that has no primary key and I am not able to add one "terrible I know" 我正在尝试使用Partition函数生成结果,但是不幸的是,我正在处理没有主键的其他表设计,而且我无法添加一个“我知道的可怕”

My sample code as below 我的示例代码如下

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)

I know I could just use a distinct to get the following results but in this instance I am going to be better of using Partition due to this being only an example of what I am trying to do so there is some more to go with this. 我知道我可以使用一个distinct获得以下结果,但是在这种情况下,我会更好地使用Partition,因为这只是我要尝试的一个示例,因此还有很多其他用途。

What I want to do is return the first value of the Hours column at every TaskNo change so the results should be 我想做的是在每个TaskNoTaskNo更改Hours返回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

I think it should look something like this but I just cant get the required results 我认为应该看起来像这样,但是我无法获得所需的结果

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

If anyone could help it would be much appreciated. 如果有人可以帮助,将不胜感激。

Thanks Phil 谢谢菲尔

You have to partition by TaskNo and OrderNo to get the results you want. 您必须按TaskNo OrderNo进行分区才能获得所需的结果。 Since you don't have any meaningful way to order the rows within those partitions you can just order by TaskNo , but there's no guarantee that you'll get the same "first" record every time without some sort of indicator of order: 由于您没有任何有意义的方式来排序这些分区中的行,因此只能通过TaskNo ,但不能保证每次没有某种顺序指示符时,您都会获得相同的“第一”记录:

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

You would use row_number() : 您将使用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;

Notice the ?? 注意?? in the query. 在查询中。 SQL tables represent unordered sets. SQL表表示无序集。 There is no first or last row within a set. 集合中没有第一行或最后一行。 You need a column that specifies the ordering. 您需要一列来指定顺序。 Whatever that column is, use it for the ?? 无论该列是什么,都将其用于?? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM