SQL Server : 过度分区
Posted
技术标签:
【中文标题】SQL Server : 过度分区【英文标题】:SQL Server : Over Partition 【发布时间】:2016-01-21 19:53:19 【问题描述】:我正在尝试使用函数Partition
来生成结果,不幸的是我正在处理没有主键的其他表设计,并且我无法添加一个“我知道的可怕”
我的示例代码如下
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,因为这只是我尝试做的一个例子,所以还有更多工作要做有了这个。
我想要做的是在每次 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
如果有人能提供帮助,将不胜感激。
谢谢菲尔
【问题讨论】:
我假设您使用的是 SQL 2012,因为您使用的是First_Value
函数?如果是这样,则 SQL 2008 标记不适用。
嗨,Stanley,是的,我正在使用 SQL Server 2012,谢谢 P
【参考方案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 表代表 无序 集合。集合中没有第一行或最后一行。您需要一个指定排序的列。无论该列是什么,都将其用于??
。
【讨论】:
嗨,戈登,感谢您的回复,非常感谢您的回答。 P【参考方案2】:您必须按TaskNo
进行分区和 OrderNo
以获得您想要的结果。由于您没有任何有意义的方式来对这些分区中的行进行排序,因此您可以按TaskNo
进行排序,但不能保证在没有某种顺序指示符的情况下每次都会获得相同的“第一”记录:
SELECT OrderNo,
TaskNo,
First_Value(Hours) OVER (PARTITION BY OrderNo , TaskNo ORDER BY TaskNo)
FROM mytable
【讨论】:
也感谢 D 的回答以上是关于SQL Server : 过度分区的主要内容,如果未能解决你的问题,请参考以下文章