Проверка того, что несколько столбцов имеют любое из нескольких значений в параметре значения таблицы - PullRequest
1 голос
/ 28 мая 2020

Я пытаюсь создать запрос, чтобы получить список учетных записей из существующей базы данных. У меня будет два списка целых чисел, переданных через два параметра значений таблицы (TVP) из C#. Затем мне нужно увидеть, есть ли в нескольких столбцах какие-либо значения в соответствующих таблицах TVP. Списки целых чисел TVP предоставляются разными клиентами и могут различаться для разных клиентов. Вот почему они являются TVP, чтобы разрешить передачу значений в качестве параметров.

Структура данных не может быть изменена, она создается на основе данных из другой системы. Комментарии об изменении структуры данных не помогут. Чтобы помочь, я расскажу о таблице в качестве примера, которая поможет показать, что мне нужно.

Глядя на следующую таблицу:

Table Accounts
  varchar(200) AccountId
  int StatusId1
  int StatusId2
  int StatusId3
  int StatusId4
  int Identifier1
  int Identifier2
  int Identifier3
  int Identifier4
  int Identifier5

Я знаю, что могу сделать sql заявление вроде:

Select AccountId from Accounts where StatusId1 In (1,2,3)

Мне удалось узнать, что я также могу отменить команду In:

Select AccountId from Accounts where 1 In (StatusId1, StatusId2, StatusId3, StatusId4)

Это только позволяет мне проверять одно значение в каждом столбце. Проблема в том, что мне нужно смешать их при использовании TVP для списка целых чисел.

Ближайшее, что мне удалось создать, это следующее:

--Load the TVP lists 
SELECT * INTO #StatusCodes FROM @StatusId
SELECT * INTO #IdentityCodes FROM @IdentifierId

--Find the Accounts that have the chosen Ids
SELECT AccountId
FROM Accounts
WHERE StatusId1 IN( SELECT Id FROM #StatusCodes)
OR StatusId2 IN( SELECT Id FROM #StatusCodes)
OR StatusId3 IN( SELECT Id FROM #StatusCodes)
OR StatusId4 IN( SELECT Id FROM #StatusCodes)
OR Identifier1 IN (SELECT Id FROM #IdentityCodes)
OR Identifier2 IN (SELECT Id FROM #IdentityCodes)
OR Identifier3 IN (SELECT Id FROM #IdentityCodes)
OR Identifier4 IN (SELECT Id FROM #IdentityCodes)
OR Identifier5 IN (SELECT Id FROM #IdentityCodes)

Этот запрос работал в моем прототипе, и я получил обратно список учетных записей, у которых был хотя бы один из этих идентификаторов. Я вижу много операторов select, и это выглядит не очень хорошо. Я тоже не уверен, насколько хорошо он работает. Мне интересно, есть ли лучший способ сделать это?

Это для системы, которая создает отчет на основе условий, которые ставят наши клиенты. Каждый клиент запускает от пары до 100 отчетов каждую ночь. Это означает, что он запускается, возможно, сотни раз каждую ночь. Хотя это не система, работающая тысячи раз в час, она обрабатывает большой объем данных. Некоторые из баз данных, которые он будет искать, будут большими с большим количеством учетных записей для поиска.

1 Ответ

0 голосов
/ 28 мая 2020

Один вариант использует exists:

select a.acountId
from accounts a
where 
    exists (
        select 1 
        from #StatusCodes s 
        where s.id in (a.StatusId1, a.StatusId2, a.StatusId3, a.StatusId4)
    )
    or exists (
        select 1 
        from #IdentityCodes i 
        where i.id in (a.Identifier1, a.Identifier2, a.Identifier3, a.Identifier4)
    )
...