2016-10-01 66 views
1

我有一列中的UserIds以逗號分隔的形式存儲(如下所示)。現在我有一個問題,我需要檢查當前用戶是否在該列表中可用。從Sql服務器中的逗號分隔值中比較Id

Id  UserId 
-- --------------- 
1 10,11,12,13  
2 10,13,15,4  

我已經使用了拆分功能,但這需要太多的時間,因爲我有數以百萬計的記錄和20個其他列。

+0

發佈問題然後立即發佈答案的要點是什麼?也許如果這是一個有趣的問題,但這不是。有很多次這個問題。 – ZLK

+0

我只是分享知識,因爲我剛剛發現了這一點,並且改善了我的存儲過程的很多性能。還有一個原因可能會有人建議我一個更好的答案,這將有助於我進一步改進。 –

回答

0

我發現了以下方法來解決上述問題。

SELECT * 
FROM dbo.History 
WHERE (','+ RTRIM(ShareWith)+',') LIKE '%,'+CAST(@UserId AS VARCHAR)+',%') 
1

另一種時尚的解決方案,以檢查這些逗號分隔的列表是一樣的東西:

樣本數據

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個規範化規則,它將使管理你的應用程序和你的生活變得更容易和更簡單:)。

+0

你說得對,但是這個模式已經被創建。 上面的答案是首先分割逗號分隔值然後檢查它。我們正在使用它,並且需要時間來執行它,因爲我們有數百萬條記錄需要執行此操作。 –

+0

認真嗎?您在生產中使用逗號分隔的數據(數百萬行),並用LIKE搜索它?你們聽說過NF嗎?如果你把這個存儲爲'id int,帶有聚集索引的userid int' - 它將會是快速搜索。只是一個問題,爲什麼? – gofr1

0

您可以使用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 
0

嘗試:

select * from yourtable 
where UserId like '%,' + idtocheck + ',%' or 
UserId like idtocheck + ',%' or 
UserId like '%,' + idtocheck or 
UserId = idtocheck 
0

你有沒有使用您的自定義拆分功能或標準的STRING_SPLIT?在Azure Sql數據庫中,您可以使用STRING_SPLIT函數來拆分字符串:

SELECT mytable.* 
FROM mytable 
    CROSS APPLY STRING_SPLIT(UserId , ',') ids 
WHERE ids.value = 3