2016-10-01 2 views
1

У меня есть столбец, в котором UserIds хранятся в форме, разделенной запятой (как показано ниже). Теперь у меня есть проблема, что мне нужно проверить, доступен ли текущий пользователь в этом списке или нет.Сравнение идентификатора из значения, разделенного запятой, на сервере Sql

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

Другой гладкий решение проверить эти разделенный запятыми список что-то вроде:

Sample Data

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 

Примечание

Но самое главное, вам необходимо исправить вашу схему, если вы используете реляционную базу данных для хранения ваших данных, делайте это правильно, следуйте простым и очень простым правилам нормализации.

Ваша схема в настоящий момент нарушает первое правило нормализации. По крайней мере, чтобы ваша база данных соответствовала первым трем нормам нормализации, и это сделает управление вашим приложением и вашей жизнью намного проще и проще :).

+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 
Смежные вопросы