簡體   English   中英

SQL Server - 使用 ROW_NUMBER() OVER PARTITION 函數來設置值

[英]SQL Server - Using ROW_NUMBER() OVER PARTITION function to SET a value

大家好,感謝您花時間研究我的問題,

背景

我正在使用 ROW_NUMER() 函數和 PARTITION BY..ORDER BY 語句來設置一個 varchar 值,在它的末尾為我的一個表中的每個值設置一個遞增的 int 值。

SELECT  component_module_id as component_module_id,
        component_property_id,
        'cf' + CAST(ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_module_id) as VARCHAR) AS cf
FROM component_property

這里的“cf”值來自每個 component_module_id 的 cf1-cfX

示例查詢輸出

我的問題

每當我嘗試在其他地方使用這些 cf 值時,例如保存在臨時表中,其他排序和分組語句都會更改這些值。 這就像生成“cf”值的語句被保存而不是“cf”值本身。

將上面的查詢插入臨時表后#t -

SELECT * FROM #t ORDER BY cf

我收到的“cf”值從 cf1 開始,然后跳轉到 cf10,然后是 cf100,cf 值的范圍從 cf1 到 cf900……我應該只接收從 c1 到 cf29 的值。

我的問題是 - 為什么此列中的值與任何其他正常值的處理方式不同? 為什么將 ROW_NUMBER() OVER (PARTITION BY....)) 計算傳遞給后續查詢? (如果這確實是正在發生的事情)。 最后,我如何將這些 'cf' 值視為正常的 VARCHAR 值,並且在我嘗試按它們分組或排序時不會改變它們。

謝謝你的幫助!

更新

我接受了拉努的建議,

“似乎你最好只存儲 int 值,並使用(PERSISTED)計算列連接你的前綴和 ROW_NUMBER 值。”

並且我的“cf”值在排序后現在正確顯示。 感謝大家標記為已解決。

嘗試這個

SELECT  component_module_id,
        component_property_id,
        'cf' + CAST(cf) AS VARCHAR(10)
FROM    (
            SELECT  component_module_id,
                    component_property_id,
                    ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_module_id) AS cf
            FROM    component_property
        ) a
ORDER BY component_module_id

您遇到的行為是因為VARCHAR通過按字母順序排序數字

您需要使用INT進行排序,然后在最后進行連接(通過將原始查詢包裝在子查詢中

但是,評論中提出了一個更好的解決方案,即僅將數字存儲為INT並使用計算列(或在查詢級別)添加前綴

如果你這樣做,它會起作用

SELECT * FROM #t ORDER BY component_module_id, cast(replace(cf, 'cf', '') as int)

問題是您同時按component_module_id分區排序。 在每個分區內,排序鍵具有相同的值。

為什么這很重要? SQL 中的排序不穩定。 這意味着可以通過任何一種方式解決關系。 再次運行查詢,您可能會得到不同的排序(在關系中)。

簡單的解決方案是將排序更改為穩定,並且您只有一列來執行該component_property_id 我還建議使用CONCAT()以便您不需要任何類型轉換:

SELECT component_module_id as component_module_id,
       component_property_id,
       CONCAT('cf',
              ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_property_id)
             0 AS cf
FROM component_property

我還應該注意,您的代碼使用沒有長度的VARCHAR 這在 SQL Server 中是一個非常糟糕的主意。 默認長度因上下文而異,對於某些值可能不夠大(盡管在這種情況下您沒有這個問題)。

更新

我接受了拉努的建議,

“似乎你最好只存儲 int 值,並使用(PERSISTED)計算列連接你的前綴和 ROW_NUMBER 值。”

並且我的“cf”值在排序后現在正確顯示。 感謝大家標記為已解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM