我有一列中的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
我只是分享知识,因为我刚刚发现了这一点,并且改善了我的存储过程的很多性能。还有一个原因可能会有人建议我一个更好的答案,这将有助于我进一步改进。 –