2015-03-11 1 views
0

У меня есть таблица мусора, с которой мне нужно извлечь данные.Выбор активных ролей из денормализованной таблицы с дубликатами

Name  | Person# | Assignment_Status | Group 
-------------------------------------------------- 
Smith, John | 1234567 | NLE    | G1 
Smith, John | 1234567 | Active   | G2 
Jones, Jane | 7654321 | Active   | G1 
James, Jack | 9876541 | LOA    | G3 
Peep, Laura | 6549871 | ServiceLOA  | G1 
Some, One | 3219875 | NLE    | G2 

Каждый раз, когда человек движется группы их текущий assignment_status получает значение NLE и новая запись получает создать, чтобы установить assignment_status на вход для новой группы. Когда человек покидает компанию, они также устанавливают значение_назначения для NLE. В этой таблице нет уникального идентификатора строки, и у нее нет отметки даты.

Мне нужен запрос, который уменьшает таблицу до 1 записи на одного сотрудника, и если у сотрудника есть несколько записей, мне нужен Assignment_Status, который не является NLE. Например, Джон Смит должен показать, что он активен для G2.

Моя первая попытка была:

SELECT * 
INTO #TempAssignments 
FROM 
    (SELECT 
     ROW_NUMBER() OVER (ORDER BY aID) AS ID, 
     Name, 
     Person#, 
     (CASE WHEN Assignment_Status='NLE' THEN 1 ELSE 0 END) AS aID, 
     Group 
    FROM 
     tblAssignments) 

С данными в временную таблицу, то я создал второй запрос для выбора МИН ID, МИН Aid и GROUP BY Имя и Person # затем присоединился что вернитесь в таблицу temp, чтобы получить группу для данного идентификатора.

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

+0

Если у вас нет индексов или ваша таблица мала, лучше использовать 'ROW_NUMBER()' (без 'GROUP BY', конечно). Если ваша таблица большая, и вы можете создать индекс на '(Person #, Assignment_Status)' и, еще лучше, если у вас есть отдельная небольшая таблица со списком всех людей, тогда было бы лучше использовать 'CROSS APPLY' , «Лучше» я имею в виду быстрее здесь. –

ответ

1

Следующий запрос:

SELECT Name, Person#, [Group] 
FROM (
    SELECT Name, Person#, [Group], 
     ROW_NUMBER() OVER (PARTITION BY Person#, Name 
          ORDER BY CASE 
             WHEN Assignment_Status <> 'NLE' THEN 0 
             ELSE 1 
            END) AS rn 
    FROM tblAssignments) t 
WHERE t.rn = 1 

будет выбрать одну запись для каждого сотрудника, как это определено пары в Person#, Name значение. Если у сотрудника есть несколько записей, тогда будет выбрана запись с Assignment_Status, которая не является NLE.

+0

Это сделало именно то, что мне нужно спасибо! – AxGryndr

Смежные вопросы