Поиск случайной выборки уникальных данных в нескольких столбцах - SQL Server

Предоставлен набор данных в базе данных SQL Server со следующими столбцами

AccountID, UserID_Salesperson, UserID_Servicer1, UserID_Servicer2

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

--SET UP TEST DATA
CREATE TABLE MY_TABLE 
(
    AccountID int, 
    UserID_Salesperson int, 
    UserID_Servicer1 int, 
    UserID_Servicer2 int
)

INSERT INTO MY_TABLE (AccountID, UserID_Salesperson, UserID_Servicer1, UserID_Servicer2) 
VALUES (12345, 1, 1, 2)
INSERT INTO MY_TABLE (AccountID, UserID_Salesperson, UserID_Servicer1, UserID_Servicer2) 
VALUES (12346, 3, 2, 1)
INSERT INTO MY_TABLE (AccountID, UserID_Salesperson, UserID_Servicer1, UserID_Servicer2) 
VALUES (12347, 4, 3, 1)
INSERT INTO MY_TABLE (AccountID, UserID_Salesperson, UserID_Servicer1, UserID_Servicer2) 
VALUES (12348, 1, 2, 3)

--VIEW THE NEW TABLE
SELECT * FROM MY_TABLE

--NORMALIZE DATA (Unique List of UserID's) 
SELECT DISTINCT MyDistinctUserIDList 
FROM
    (SELECT UserID_Salesperson as MyDistinctUserIDList, 'Sales' as Position 
     FROM MY_TABLE
     UNION 
     SELECT UserID_Servicer1, 'Service1' as Position 
     FROM MY_TABLE
     UNION 
     SELECT UserID_Servicer2, 'Service2' as Position 
     FROM MY_TABLE) MyDerivedTable

--NORMALIZED DATA
SELECT * 
FROM
    (SELECT AccountID, UserID_Salesperson as MyDistinctUserIDList, 'Sales' as Position 
     FROM MY_TABLE
     UNION 
     SELECT AccountID, UserID_Servicer1, 'Service1' as Position 
     FROM MY_TABLE
     UNION 
     SELECT AccountID, UserID_Servicer2, 'Service2' as Position 
     FROM MY_TABLE) MyDerivedTable

DROP TABLE MY_TABLE

В этом примере таблицы я мог бы выбрать AccountID (12347 и 12348) ИЛИ (12347 и 12346), чтобы получить наименьшее количество учетных записей со всеми пользователями.

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

Всего 1 ответ


Я не знаю, как вы гарантируете наименьшее количество идентификаторов учетных записей, но вы можете получить одну строку для каждого идентификатора пользователя, используя:

select t.*
from (select t.*,
             row_number() over (partition by UserId order by newid()) as seqnum
      from my_table t cross apply
           (values (t.UserID_Salesperson), (t.UserID_Servicer1), (t.UserID_Servicer2)
           ) v(UserID)
     ) t
where seqnum = 1;

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

select top (1) with ties t.*
from (select t.*,
             row_number() over (partition by UserId order by newid()) as seqnum
      from my_table t cross apply
           (values (t.UserID_Salesperson), (t.UserID_Servicer1), (t.UserID_Servicer2)
           ) v(UserID)
     ) t
where seqnum = 1
order by row_number() over (partition by accountID order by accountID);

Есть идеи?

10000