[英]Reading 0.5 value in ROW_NUMBER() and PARTITION BY | SQL Server 2012
[英]SQL Server 2012: Conditionally Incrementing a counter user ROW_NUMBER()
我正在嘗試應用ROW_NUMBER()
來根據特定條件遞增計數器。
我的數據看起來像這樣,目標計數器是Prep
列
id DSR PrepIndicator Prep
--------------------------------------
1662835 -1 1 1
1662835 14 2 2
1662835 14 2 3
1662835 20 2 4
1667321 -1 1 1
1667321 30 2 2
1667321 14 2 3
1680648 -1 1 1
1680648 14 2 2
1680648 60 1 1
1680648 14 2 2
1680648 14 2 3
1683870 -1 1 1
1683870 12 2 2
1683870 10 2 3
1683870 60 1 1
1683870 7 2 2
PrepIndicator
忽略PrepIndicator
列,我試圖實現的業務邏輯如下:
Prep
計數器。 實際上, PrepIndicator
會創建一個標志來實現它,如果PrepIndicator = 1
則Prep = 1
。 如果PrepIndicator = 2
,則增加Prep
。
如果可能的話,我更願意在沒有PrepIndicator
專欄的情況下實現這一PrepIndicator
。
如何使用ROW_NUMBER()
實現此條件增量?
我試過了
ROW_NUMBER() OVER (PARTITION BY id, PrepIndicator ORDER BY id)
但是當DSR
>= 42
時它似乎不起作用。
任何建議或幫助都會很棒。 謝謝!
首先,您需要明確的訂購。 如果你有一個以前的值,“遞增計數器”只有意義。 您可以向表中添加IDENTITY列,或使用ROW_NUMBER() OVER ORDER BY(/* your logic here */)
。 在您的表中,您甚至沒有前三列的唯一值(請參閱1680648,14,2),因此我認為添加ID是可行的方法。
為了做你想要達到的目標,我相信你必須在循環中做到這一點。 如果您使用ROW_NUMBER()
您可能希望選擇一個臨時表。 根據您的問題的性質,術語計數器表示您將擁有一個變量。
UPDATE TableA SET rowId = ROW_NUMBER() OVER(ORDER BY id, DSR, PrepIndicator)
然后“有條件的”似乎表明了CASE的良好用途
DECLARE @counter INT = 1
DECLARE @row INT = 1
DECLARE @DSR INT
UPDATE TableA SET Prep = @counter
SET @row = (SELECT rowId FROM TableA WHERE rowId > @row)
WHILE EXISTS( SELECT TOP 1 1 FROM TableA WHERE rowId = @row )
BEGIN
SELECT @DSR = DSR FROM TableA WHERE rowId = @row
SET @counter = CASE WHEN @DSR < 42 THEN @counter + 1 ELSE 1 END
UPDATE TableA SET Prep = @counter WHERE rowId = @row
SET @row = (SELECT rowId FROM TableA WHERE rowId > @row)
END
首先,您需要添加主鍵,因為SQL表中沒有物理順序; 我們可以稱之為IdK。 然后,以下代碼應該為您提供所需內容:
select *, row_number() over (partition by Id, (Select Count (*) from MyTable t2 where t2.idk <= t1.idk and t2.id = t1.id and DSR >= 42) order by idk) prep
from MyTable t1
order by idk
至於為什么你的代碼不起作用,這是因為在分區/編號完成之前首先對行進行分組。 在分區的兩列id和PrepIndicator的情況下,我們在編號之前的最后5行獲得以下中間結果:
id DSR PrepIndicator Row_Number (Id, PrepIndicator)
1683870 -1 1 1
1683870 60 1 2
1683870 12 2 1
1683870 10 2 2
1683870 7 2 3
請注意,DSR = 60的行現在位於第二個位置。 這顯然是你不想擁有的。 在Select count(*)...的情況下,我們在分組完成后的最后5行中得到以下結果,就在編號之前:
id DSR ...Count() Row_Number (Id, ...Count())
1683870 -1 0 1
1683870 12 0 2
1683870 10 0 3
1683870 60 1 1
1683870 7 1 2
您可以注意到,在這種情況下,任何行的位置都沒有變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.