2012-05-28 3 views
1

У меня есть таблица сотрудников с такими столбцами, как emp_id, firstname, lastname, region_id, status и effective_date.Как получить последнюю запись сотрудника в оракуле?

Таблица служащих может иметь несколько записей для одного и того же сотрудника с разными датами и статусами эффективности.

Сотрудник может иметь два статуса «Ливер» и «Столяр».

id  emp_id firstname  region status  effective_date 
1  1   James  Asia  Joiner  1-Jan-2012 
2  1   James  UK  Leaver  1-Aug-2012 
3  1   James  USA  Joiner  1-Aug-2012 
4  1   James  Asia  Leaver  1-May-2012 
5  1   James  UK  Joiner  1-May-2012 
6  1   James  USA  Leaver  1-Sep-2012 

С учетом указанных выше данных в таблице сотрудников, если я хочу, чтобы получить последнюю запись Джемса по состоянию на 1 января 2012 года, я хотел бы получить запись с идентификатором = 1,

Если я хочу, чтобы получить последняя запись Джеймсу, как на 1 мая 2012 года, я хотел бы получить запись с идентификатором = 5

Если я хочу, чтобы получить последнюю запись Джемса, как на 1 августа 2012 года, я хотел бы получить запись с идентификатором = 3,

Если я хочу получить последнюю запись о james, так как 1 сентября 2012 года, я бы получил запись с id = 6

После запроса правильно дает мне последнюю запись

SELECT 
     emp_id, 
     MAX(effective_date) AS latest_effective_date 
FROM 
     EMPLOYEE 
GROUP BY 
     emp_id 

Но как я могу получить другие столбцы, такие как FirstName, регион и т.д.

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

+0

Не могли бы вы объяснить это, пожалуйста? «Если я хочу получить последнюю запись о Джеймсе, как 1 августа 2012 года, я бы получил запись с id = 3» почему бы не 2? – Sebas

+0

@Sebas. Конечно, Джеймс переезжает из региона Великобритании в США 1 августа 2012 года. Итак, если мне нужно посмотреть, где Джеймс, как 1 августа 2012 года, он должен вернуть США, а не Великобританию. Следовательно, запись с id = 3, а не id = 2. – ashishjmeshram

+1

, тогда вся ваша логика должна быть пересмотрена, ваш собственный запрос возвращает «правильно последнюю запись» только случайно. Я сейчас ушел из этой темы, у вас есть аналитические проблемы для решения. – Sebas

ответ

0

попробовать:

SELECT * 
FROM EMPLOYEE emp 
INNER JOIN (SELECT max(id) AS id 
     emp_id, 
     MAX(effective_date) AS latest_effective_date 
FROM 
     EMPLOYEE 
GROUP BY 
     emp_id) AS employee_1 on emp.id = employee_1.id 
+0

Идентификаторы не могут быть сгенерированы в последовательности. Пользователи могут вводить запись для 1-sep-2012 в системе, прежде чем вставлять запись за 1 августа 2012 года (т. Е. Прогнозирование). – ashishjmeshram

2

Вам необходимо внутреннее соединение запроса у вас уже есть обратно в таблицу Employee, чтобы ограничить записи:

SELECT Emp.* 
FROM Employee Emp 
     INNER JOIN 
     ( SELECT Emp_ID, MAX(effective_date) AS latest_effective_date 
      FROM Employee 
      GROUP BY Emp_ID 
     ) MaxEmp 
      ON Emp.Emp_ID = MaxEmp.Emp_ID 
      AND Emp.Effective_Date = MaxEmp.latest_effective_date 
+0

Nopes, не работает. – ashishjmeshram

+2

Я не могу предложить улучшения/исправления, основанные на этой обратной связи. Почему он не работает, не работает ли он? Выполняется ли это, но не с результатами, которые вы ожидали? – GarethD

1

запрос вы ввели не обязательно возвращать записи с идентификаторами 3, 5, 6, как вы заявили ранее, потому что в этом случае:

2  1   James  Asia  Leaver  1-May-2012 
3  1   James  UK  Joiner  1-May-2012 

Effective_Date равен для обеих строк, и он, вероятно, вернет запись с идентификатором 2, а не 3.

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

9
SELECT * FROM 
(SELECT 
    e.*, 
    ROW_NUMBER() OVER (partition by emp_id order by effective_date DESC) r 
FROM 
    EMPLOYEE e) 
WHERE r = 1; 

Выше вы получите запись с максимальной эффективностью__Date для каждого отдельного emp_id.

Ваше второе требование о возвращении записи на данную дату следует fullfiled этим запросом:

(«статус ASC» - будет заботиться о принятии статуса «Столяр», если есть и «Ливер» на ту же дату .)

SELECT * FROM 
(SELECT 
    e.*, 
    ROW_NUMBER() OVER (partition by emp_id order by effective_date DESC, status ASC) r 
FROM 
    EMPLOYEE e 
WHERE effective_date <= '<your desired date>') 
WHERE r=1; 
1

Постарайся это один

SELECT 
    MAX(id) KEEP (DENSE_RANK FIRST ORDER BY effective_date DESC) id, 
    MAX(emp_id) KEEP (DENSE_RANK FIRST ORDER BY effective_date DESC) emp_id, 
    MAX(firstname) KEEP (DENSE_RANK FIRST ORDER BY effective_date DESC) firstname, 
    MAX(status) KEEP (DENSE_RANK FIRST ORDER BY effective_date DESC) status, 
    MAX(effective_date) KEEP (DENSE_RANK FIRST ORDER BY effective_date DESC) effective_date 
FROM Employee GROUP BY firstname