Поиск всех вхождений значения столбца, которых нет в другой таблице в SQL - PullRequest
0 голосов
/ 27 мая 2020

Моя проблема заключается в следующем:

У меня две таблицы: первая таблица имеет два столбца (person_id и account_ids столбцы). В столбце Account_ids присутствуют идентификаторы учетных записей, разделенных запятыми:

Person_ID    Account_ids
-----------------------------------------------------------------
  123        000000grVA6AM,000016ILMhAO, 000000ihi4MAQ, 000000TF5MAQQ,000000TF5MAHZ
  124        000000frVA6AM,000016ILMhAO
  125        000000frVA6BC,000024ILMhJZ, 000000frXC6A,000024YTMhA

Вторая таблица содержит сведения о person_id

Person_ID   Account_ID      Account_Name
----------------------------------------
  123       000000grVA6AM     Name1
  123       000016ILMhAO      Name2
  123       000000ihi4MAQ     Name3
  123       000000TF5MAQQ     Name4
  123       000000TF5MAHZ     Name5
  124       000016ILMhAO      Name2
  124       000000TF5MAHZ     Name5
  124       000000frVA6AM     Name6
  124       000024ILMhAO      Name7
  124       000000frVA7XZ     Name8
  125       000000frVA6BC     Name9 
  125       000024ILMhJZ      Name10
  125       000000frXC6A      Name11
  125       000024YTMhA       Name12
  125       000024IXThJY      Name13

Я хочу найти все account_ids для каждого person_id, которые не в таблице 1 для этого Person_ID. Например, из приведенного выше примера ответ должен быть:

Person_ID   Account_ID      Account_Name
-----------------------------------------

   124      000000TF5MAHZ     Name5
   124      000024ILMhAO      Name7
   124      000000frVA7XZ     Name8
   125      000024IXThJY      Name13

Как мне это сделать?

Я пытался применить предложение «Не нравится», но потом я не понял, как разделите значения, разделенные запятыми, в таблице 1. Пожалуйста, помогите!

Спасибо!

ОБНОВЛЕНИЕ:

Запрос на создание временной таблицы, чтобы его было легче проверить:

CREATE TEMP table persons
( person_id int, account_id varchar(20), account_name varchar(10))

insert into persons values
 (123,       '000000grVA6AM',     'Name1');
 insert into persons values
  (123,       '000016ILMhAO',      'Name2');
  insert into persons values
  (123,       '000000ihi4MAQ',     'Name3');
  insert into persons values
  (123,       '000000TF5MAQQ',     'Name4');
  insert into persons values
  (123,       '000000TF5MAHZ',     'Name5');
  insert into persons values
  (124,      '000016ILMhAO',      'Name2');
  insert into persons values
  (124,       '000000TF5MAHZ',     'Name5');
  insert into persons values
  (124,      '000000frVA6AM',     'Name6');
  insert into persons values
  (124,       '000024ILMhAO',      'Name7');
  insert into persons values
  (124,       '000000frVA7XZ',     'Name8');
  insert into persons values
  (125,       '000000frVA6BC',     'Name9');
  insert into persons values 
  (125,       '000024ILMhJZ',      'Name10');
  insert into persons values
  (125,       '000000frXC6A',      'Name11');
  insert into persons values
  (125,       '000024YTMhA',       'Name12';
  insert into persons values
  (125,       '000024IXThJY'      'Name13');

Для таблицы счетов:

CREATE TEMP table accounts
(person_id int, account_ids varchar(100))

insert into accounts values
(123,        '000000grVA6AM,000016ILMhAO, 000000ihi4MAQ, 000000TF5MAQQ,000000TF5MAHZ');
insert into accounts values
  (124,        '000000frVA6AM,000016ILMhAO');
insert into accounts values
  (125,        '000000frVA6BC,000024ILMhJZ, 000000frXC6A,000024YTMhA');

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

Мы можем попробовать:

SELECT p.Person_ID, p.Account_ID, p.Account_Name
FROM persons p
WHERE NOT EXISTS (SELECT 1 FROM accounts a
                  WHERE ',' || a.Account_ids || ',' LIKE '%,' || p.AccountID || ',%');

Обратите внимание, что хранение ваших учетных записей в виде данных CSV в одном столбце не является оптимальным дизайном базы данных, потому что такие данные не нормализованы . Чтобы написать желаемый запрос, нам пришлось провести строковую олимпиаду, чтобы проверить наличие каждой учетной записи в строке CSV. Если бы все эти учетные записи были в отдельных записях, наша задача была бы проще.

Изменить:

Если в данных вашей учетной записи CSV действительно есть пробелы, сравните используя замену, которая сначала удаляет их:

WHERE NOT EXISTS (SELECT 1 FROM accounts a
                  WHERE ',' || REPLACE(a.Account_ids, ' ', '')  || ','
                        LIKE '%,' || p.AccountID || ',%');
0 голосов
/ 27 мая 2020

Если вы используете SQL Server 2016 или выше, вы можете использовать функцию STRING_SPLIT () для разделения значений CSV для независимых тестов, например:

select b.*
from (
  select Person_ID, Account_ID
  from dbo.Table2
  except
  select Person_ID, trim(Value)
  from dbo.Table1
  cross apply string_split(Account_ids, N',')
) a
join dbo.Table2 b on b.Person_ID=a.Person_ID and b.Account_ID=a.Account_ID

Примечание. trim(Value), который отбрасывает любые пробелы вокруг идентификаторов учетных записей в столбце Account_ids, для чего требуется SQL Server 2017 или выше, вы можете использовать ltrim(rtrim(Value)) в более ранних версиях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...