我有下面的问题,我必须在SQL中解决。该数据库在SQL-Server 2005上运行。 对于一组(年份和数字),该组应该是唯一的,例如在下面的集合中我应该有4组(1 - 4)而不是组(1-2)。 我不被允许更新表格,我无法修复该应用程序。
我可以为我的套装计算4个不同的组,还是有不同的方法来解决问题?
year |number |row |group<br>
2004 |1000 |1 |1<br>
2004 |1000 |2 |1<br>
2004 |1000 |3 |1<br>
2004 |1000 |4 |1<br>
2004 |1000 |5 |2<br>
2004 |1000 |6 |2<br>
2004 |1000 |7 |2<br>
2004 |1000 |8 |2<br>
2004 |1000 |9 |1<br>
2004 |1000 |10 |1<br>
2004 |1000 |11 |1<br>
2004 |1000 |12 |1<br>
2004 |1000 |13 |2<br>
2004 |1000 |14 |2<br>
2004 |1000 |15 |2<br>
2004 |1000 |16 |2<br>
答案 0 :(得分:0)
如果我理解正确,你可以使用窗口功能。对于此特定问题,您可以对行号使用算术。对于更一般的解决方案,这是一个“间隙和岛屿”问题。在SQL Server 2005中,您可以使用窗口函数来解决此问题:
select t.*,
dense_rank() over (partition by year, number order by group, seqnum_r - seqnum_rg) as grp
from (select t.*,
row_number() over (partition by year, number order by row) as seqnum_r,
row_number() over (partition by year, number, group order by row) as seqnum_rg
from t
) t;
了解其工作原理有点棘手。重要的是,对于具有相似值的“岛”,两个序列号之间的差异是恒定的。 dense_rank()
然后只提供最终值。
以上将产生四组,但它们的顺序可能不正确。为此,使用另一轮窗口函数来获得最小id
:
select t.*,
dense_rank() over (partition by year, number order by minid) as grp
from (select t.*, min(id) over (partition by year, number, group, seqnum_r - seqnum_rg) as minid
from (select t.*,
row_number() over (partition by year, number order by row) as seqnum_r,
row_number() over (partition by year, number, group order by row) as seqnum_rg
from t
) t
) t;