2016-10-01 35 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