2016-03-01 2 views
0

У меня есть список записей в моей таблице:Как фильтровать записи в SQL

emp_id emp_status emp_date 
0001  P   1/1/2012 
0001  P    3/1/2014 
0001  P    4/1/2015 
0001  R    3/1/2016 

Пусть говорят R = уволиться и P = присутствует. В этой таблице я пытаюсь написать функцию, чтобы получить год обслуживания. Сейчас я боюсь, что я могу получить первый настоящий день (1/1/2012) для этого сотрудника и передать его в @join_Date. Однако, когда я зацикливаюсь на этой записи (используя курсор), вторая дата P заменяет первую, но мне нужна только первая дата присоединения как 1/1/2012. но теперь моя дата присоединения - 3/1/2014. Кто-нибудь знает, как я могу это исправить? Код предоставляется

Declare @join_date datetime 
    Declare myCursor Cursor for 
    Select * From t_emp_info where emp_id = @emp_id 
    order by emp_date desc 

     SET @result = 0 
    SET @join_date = null 

    OPEN myCursor 

     FETCH NEXT FROM myCursor INTO @emp_date, @emp_status 
    IF @emp_status = 'P' AND @join_date IS null 

     //Logic 
     Begin 
      Set @join_date = @emp_date 
    End 
    IF @emp_status = 'R' AND @join_date IS NOT null 

     //Logic 

    End 

Ожидаемый результат:

@join_date = 1/1/2012

Фактический результат: @join_date = 3/1/2016

+1

Где вы присвоить значение в join_date? – Yossi

+0

В инструкции First If я обновил код – RedRocket

+1

И есть ли другие места, которые касаются join_date? Попытайтесь разместить его перед объявлением курсора? – Yossi

ответ

1

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

Если вы ищете первую дату для каждого сотрудника, сгруппируйте строки по идентификатору сотрудника, упорядочите по дате и затем выберите первый результат. Например:

SELECT 
    emp_id, 
    emp_date AS join_date, 
    ROW_NUMBER() OVER (PARTITION BY emp_id order by emp_date) as rn 
FROM t_emp_info 
WHERE emp_status = 'P' AND rn = 1 

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

Если сотрудники могут уйти и вернуться, и предпочтительно принять последнюю дату воссоединиться, то сделать что-то вроде этого:

;WITH ORDERED AS 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY emp_id ORDER BY emp_date) as rn 
    FROM t_emp_info 
), REJOINING AS 
(
    SELECT P.* 
    FROM ORDERED R 
     LEFT JOIN ORDERED P ON P.rn = R.rn + 1 
    WHERE R.emp_status='R' AND P.emp_status='P' 
) 
SELECT 
    P1.emp_id, 
    MAX(ISNULL(P2.emp_date,P1.emp_date)) AS join_date 
FROM ORDERED P1 
    LEFT JOIN REJOINING P2 ON P2.rn > P1.rn 
WHERE P1.emp_status='P' AND rn = 1 
GROUP BY P1.emp_id 
+0

Умм, что делать, если у меня есть запись, подобная PPRPP? Как сотрудник уходит в отставку и возвращается? Я хочу взять первый первый P после R. – RedRocket

+0

спасибо, получил его работу. – RedRocket

1

Вы можете получить это значение с помощью агрегатной функции, например:

select emp_id, min(emp_date) as join_date from t_emp_info i where emp_status='P' group by emp_id; 

или, для одного сотрудника:

select min(emp_date) as join_date from t_emp_info i where [email protected]_id and emp_status='P'; 
Смежные вопросы