我有一列中的UserIds以逗號分隔的形式存儲(如下所示)。現在我有一個問題,我需要檢查當前用戶是否在該列表中可用。從Sql服務器中的逗號分隔值中比較Id
Id UserId
-- ---------------
1 10,11,12,13
2 10,13,15,4
我已經使用了拆分功能,但這需要太多的時間,因爲我有數以百萬計的記錄和20個其他列。
我有一列中的UserIds以逗號分隔的形式存儲(如下所示)。現在我有一個問題,我需要檢查當前用戶是否在該列表中可用。從Sql服務器中的逗號分隔值中比較Id
Id UserId
-- ---------------
1 10,11,12,13
2 10,13,15,4
我已經使用了拆分功能,但這需要太多的時間,因爲我有數以百萬計的記錄和20個其他列。
我發現了以下方法來解決上述問題。
SELECT *
FROM dbo.History
WHERE (','+ RTRIM(ShareWith)+',') LIKE '%,'+CAST(@UserId AS VARCHAR)+',%')
另一種時尚的解決方案,以檢查這些逗號分隔的列表是一樣的東西:
樣本數據
Declare @Table TABLE(Id INT,UserId VARCHAR(50))
INSERT INTO @Table VALUES
(1 , '10,11,12,13'),
(2 , '10,13,15,4');
查詢
Declare @UserIDToCheck INT = 10; --<-- Id to check
SELECT *
FROM (
SELECT Id
, RTRIM(LTRIM(Split.a.value('.', 'VARCHAR(100)'))) UserID
FROM
(
SELECT Id
, Cast ('<X>' + Replace(UserId, ',', '</X><X>') + '</X>' AS XML) AS Data
FROM @Table
) AS t
CROSS APPLY Data.nodes ('/X') AS Split(a)
)A
WHERE UserID = @UserIDToCheck
注意
但最重要的是,如果您使用任何關係數據庫存儲數據,請按照正常化的簡單和非常基本的規則進行操作,但最重要的是您需要修復您的模式。
您的架構此刻違反了規範化的第一條規則。至少讓你的數據庫符合前3個規範化規則,它將使管理你的應用程序和你的生活變得更容易和更簡單:)。
你說得對,但是這個模式已經被創建。 上面的答案是首先分割逗號分隔值然後檢查它。我們正在使用它,並且需要時間來執行它,因爲我們有數百萬條記錄需要執行此操作。 –
認真嗎?您在生產中使用逗號分隔的數據(數百萬行),並用LIKE搜索它?你們聽說過NF嗎?如果你把這個存儲爲'id int,帶有聚集索引的userid int' - 它將會是快速搜索。只是一個問題,爲什麼? – gofr1
您可以使用XML來從逗號分隔值獲得一個表:
DECLARE @x xml,
@UserId int = 10
SELECT @x = (
SELECT id as '@id',
CAST('<u>'+REPLACE(UserId,',','</u><u>') +'</u>' as xml)
FROM YourTable
FOR XML PATH('row')
)
SELECT t.v.value('../@id','int') as id
FROM @x.nodes('/row/u') as t(v)
WHERE t.v.value('.','int') = @UserId
輸出:
id
1
2
嘗試:
select * from yourtable
where UserId like '%,' + idtocheck + ',%' or
UserId like idtocheck + ',%' or
UserId like '%,' + idtocheck or
UserId = idtocheck
你有沒有使用您的自定義拆分功能或標準的STRING_SPLIT?在Azure Sql數據庫中,您可以使用STRING_SPLIT函數來拆分字符串:
SELECT mytable.*
FROM mytable
CROSS APPLY STRING_SPLIT(UserId , ',') ids
WHERE ids.value = 3
發佈問題然後立即發佈答案的要點是什麼?也許如果這是一個有趣的問題,但這不是。有很多次這個問題。 – ZLK
我只是分享知識,因爲我剛剛發現了這一點,並且改善了我的存儲過程的很多性能。還有一個原因可能會有人建議我一個更好的答案,這將有助於我進一步改進。 –