Каков лучший способ делать select настоящего контракта и предыдущего контракта служащего в той же линии?

Хорошие, я программирую консультации в Oracle 11g и PostgreSQL 9.4, и они попросили у меня реализовывать консультацию, вывод которой появляется в следующем изображении.

Salida de consulta

Employee_ID принадлежит таблице персонала; Current_Contract_ID и Previous_Contract_Id - то же поле Contract_id таблицы контрактов, они просят у меня программировать query, где он явился настоящим контрактом и предыдущим контрактом служащего в той же линии.

Каков лучший способ программировать вышеупомянутую консультацию?

Такой он такой, как имеются подмостки tablas

0
задан 08.11.2016, 20:17
4 ответа

Самый чистый query, который я смог думать в эти часы, - этот, если нет предварительного контракта, query должен возвращаться NULL в этом поле; возможно определять стоимость DEFAULT для не расположенных напротив реестров, но он должен бы быть типа DATE но также возможно использовать COALESCE и один CAST чтобы менять этот NULL в другой текст того, чтобы быть необходим.

SELECT DISTINCT EMPLOYEE_ID, CITY_ID, NOMBRE, APELLIDO,
LAG(CONTRACT_ID, 0 ) OVER (PARTITION BY EMPLOYEE_ID ORDER BY contratos.START_DATE ASC),
LAG(CONTRACT_ID, 1 ) OVER (PARTITION BY EMPLOYEE_ID ORDER BY contratos.START_DATE ASC)
FROM empleados
LEFT JOIN ciudades ON empleados.CITY_ID = ciudades.CITY_ID
LEFT JOIN contratos ON empleados.EMPLOYEE_ID = contratos.EMPLOYEE_ID 
ORDER BY contratos.START_DATE

Единственный недостаток - что DISTINCT нужно применяться в EMPLOYEE_ID и следовательно поле не выходит в команде ты можешь выбирать правильный порядок, если ты окружаешь этот query с другим query:

SELECT CITY_ID, NOMBRE, (orden correcto)... FROM (...TODO EL QUERY ANTERIOR...) alias

Я надеюсь, что он помогает тебе.

1
ответ дан 24.11.2019, 12:41

Функции тип windowing

Существуют функции типа windowing, чтобы делать эти задания: https://www.postgresql.org/docs/current/static/functions-window.html

Она funciГіn lag дает тебе renglГіn наверху и lead renglГіn нижний. Если ты только хочешь показать Гєltimo renglГіn (с наверху) нужно помещать select внутри другого, чтобы просачиваться в конце концов. Идет пример для того, чтобы поняли:

select * from (
  select empleados.*, ciudades.ciudad, 
        contratos.contract_id, 
        contratos.start_date,
        contratos.end_date,
        lag(contratos.contract_id) over (partition by empleados.employee_id order by contratos.start_date) as contrato_anterior,
        lag(contratos.start_date) over (partition by empleados.employee_id order by contratos.start_date) as contrato_anterior_start_date,
        lag(contratos.end_date) over (partition by empleados.employee_id order by contratos.start_date) as contrato_anterior_end_date
    from contratos 
      inner join empleados on contratos.employee_id=empleados.employee_id
      left join ciudades on ciudades.city_id = empleados.city_id
  ) select_base_con_todo_junto
  where end_date is null;

versiГіn завершает

Я поместил одну versiГіn полная с insert и поверьте table в: http://rextester.com/EPM24088

1
ответ дан 24.11.2019, 12:41

Я понимаю, что она lГіgica, что определяет настоящий и предыдущий контракт, - стоимость колонны start_date. Если это случай, используя row_number() и условные добавления, возможно доставать ее informaciГіn таким образом:

with ct as (
  select employee_id,
         max(case when rnk = 1 then contract_id end) as current_contract_id,
         max(case when rnk = 2 then contract_id end) as previous_contract_id
    from (select contract_id,
                 employee_id,
                 row_number() over (partition by employee_id order by start_date desc) as rnk
            from contratos) c
   group by employee_id
)
select c.ciudad,
       e.employee_id,
       e.nombre,
       e.apellido,
       ct.current_contract_id,
       ct.previous_contract_id
  from empleados e
  join ciudades c
    on c.city_id = e.city_id
  join ct
    on ct.employee_id = e.employee_id

Консультация deberГ, - чтобы функционировать в обоих Oracle и PostgreSQL.

0
ответ дан 24.11.2019, 12:41
SELECT CITIES.CITYID, A.EMPLOYEEID, EMPLOYEES.NOMBRE AS NAME, EMPLOYEES.LASTNAME, A.CURRENTCONTRACTID, B.PREVIOUSCONTRACTID
FROM (
  (
    (
      SELECT  EMPLOYEES.EMPLOYEEID, MAX(CONTRACTID) AS CURRENTCONTRACTID FROM 
      EMPLOYEES INNER JOIN CONTRACTS ON EMPLOYEES.EMPLOYEEID = CONTRACTS.EMPLOYEEID
      GROUP BY EMPLOYEES.EMPLOYEEID
      )  AS A 
      LEFT JOIN (SELECT EMPLOYEEID, MAX(PREVIOUSCONTRACTIDG) AS PREVIOUSCONTRACTID FROM
      (
       SELECT C.EMPLOYEEID, C.PREVIOUSCONTRACTIDG FROM
          ( 
            SELECT  EMPLOYEEID, CONTRACTID AS PREVIOUSCONTRACTIDG FROM CONTRACTS ) AS C
          INNER JOIN
          (
            SELECT  EMPLOYEEID, MAX(CONTRACTID) AS PREVIOUSCONTRACTIDG FROM CONTRACTS GROUP BY EMPLOYEEID
           ) AS D
          ON C.EMPLOYEEID = D.EMPLOYEEID 
          WHERE C.PREVIOUSCONTRACTIDG < D.PREVIOUSCONTRACTIDG
          )
          GROUP BY EMPLOYEEID
        )  AS B ON A.EMPLOYEEID = B.EMPLOYEEID
      ) 
   INNER JOIN EMPLOYEES ON A.EMPLOYEEID = EMPLOYEES.EMPLOYEEID
 ) 
INNER JOIN CITIES ON EMPLOYEES.CITYID = CITIES.CITYID

Вместо Поля 'ЯМСА' в таблице 'EMPLOYEE' utilicГ© 'ИМЯ', а следовательно я поместил ему прозвище в поле.

0
ответ дан 24.11.2019, 12:41