Меня попросили эффективно получить результаты из нескольких таблиц на основе строковой входной переменной. Это «пользовательский фильтр», где мне посылают некоторые слова (мне, потому что парень пишет процедуру), и мне нужно вернуть список пользователей, которые соответствуют этой строке. Для поиска необходимо найти любое из «разделенных пробелами» слов в пользовательских данных И именах ролей, к которым они принадлежат.
Вот некоторый SQL, чтобы попытаться объяснить это. Он повторно запускается и использует только переменные таблицы.
SET NOCOUNT ON
DECLARE @InputString1 VARCHAR(20) = 'Jennifer'
DECLARE @InputString2 VARCHAR(20) = 'User'
DECLARE @Role TABLE (
Id INT NOT NULL,
RoleName VARCHAR(20)
)
DECLARE @User TABLE (
Id INT NOT NULL,
Username VARCHAR(20)
)
DECLARE @UserRole TABLE (
UserId INT,
RoleId INT
)
INSERT INTO @Role VALUES (1, 'User')
INSERT INTO @Role VALUES (2, 'Admin')
INSERT INTO @Role VALUES (3, 'Reader')
INSERT INTO @User VALUES (1, 'Craig')
INSERT INTO @User VALUES (2, 'Kirsten')
INSERT INTO @User VALUES (3, 'Jennifer')
INSERT INTO @User VALUES (4, 'Brodie')
INSERT INTO @User VALUES (5, 'Usermore')
INSERT INTO @UserRole VALUES (1,1)
INSERT INTO @UserRole VALUES (1,2)
INSERT INTO @UserRole VALUES (2,2)
INSERT INTO @UserRole VALUES (3,1)
INSERT INTO @UserRole VALUES (3,2)
INSERT INTO @UserRole VALUES (3,3)
INSERT INTO @UserRole VALUES (5,2)
-- Normal select
SELECT u.Username, r.RoleName
FROM @User u
LEFT JOIN @UserRole ur
ON ur.UserId = u.Id
LEFT JOIN @Role r
ON r.Id = ur.RoleId
-- Expected.
SELECT 'Craig' AS Username, 'User,Admin' AS Roles
UNION SELECT 'Kirsten', 'Admin'
UNION SELECT 'Jennifer', 'User,Admin,Reader'
UNION SELECT 'Brodie', ''
UNION SELECT 'Usermore', 'Admin'
-- InputString 1 would find:
SELECT 'Jennifer' AS Username, 'User,Admin,Reader' AS Roles
-- InputString 2 would find:
SELECT 'Craig' AS Username, 'User,Admin' AS Roles
UNION SELECT 'Jennifer', 'User,Admin,Reader'
UNION SELECT 'Usermore', 'Admin'
То, о чем я думал, правильно или неправильно, было получить эти строки, объединенные в одну строку (так, поскольку у пользователя может быть 0: много ролей - мне нужно левое соединение), а затем получить роли на тот же ряд.
Как только это было сделано, я думал о CONCAT во всех областях, которые меня интересуют (в реальной жизни, это электронная почта, телефон, имя пользователя, полное имя и роли) в строку, и каким-то образом ищите в этой строке любую запятую отдельные входные строки. (Возможно, у меня есть функция split, чтобы поместить их во временную таблицу?)
Это самый эффективный способ поиска нужных мне данных. У меня нет доступа к полнотекстовому поиску или чему-то в этом роде. У меня есть стандартная база данных SQL Azure, в которой мне нужно искать.
Таблица пользователей содержит около 150 000 строк, а таблица ролей - около 40 ролей. В среднем пользователю назначено 4 роли.
Количество передаваемых слов обычно составляет 1 (Крейг), возможно, может быть 2 (Чтобы найти всех «Крейгов» с ролью «Администратор»), но мы можем ограничить до 3 для производительности.
Любая помощь с этим будет очень признательна.