Как я могу объединить две таблицы с учетом заданных интервалов

#sql #database #oracle #join

#sql #База данных #Oracle #Присоединиться

Вопрос:

Я пытаюсь соединить два стола

 WITH A AS (
(SELECT 'KIM' AS NAME,
       '20160503' AS DATE
FROM DUAL)
UNION
(SELECT 'LEE' AS NAME,
       '20160307' AS DATE
FROM DUAL)
UNION
(SELECT 'PARK' AS NAME,
       '20170728' AS DATE
FROM DUAL)
),

B AS (
(SELECT '20160227' AS INTERVAL,
        '1' AS NUM
FROM DUAL)
UNION
(SELECT '20160520' AS INTERVAL,
        '2' AS NUM
FROM DUAL)
UNION
(SELECT '20170825' AS INTERVAL,
        '3' AS NUM
FROM DUAL)
)
 

В этой ситуации я хочу сделать записи в A, соединенные с B, как показано ниже

«КИМ’ ‘20160503’ ‘20160227’ ‘1’

‘LEE’ ‘20160307’ ‘20160227 ‘1’

«ПАРК’ ‘20170728’ ‘20160520’ ‘2’

Самое главное, что таблица A вообще не меняется, но таблица B изменяется в зависимости от некоторых ситуаций.

Итак, теперь я не могу просто использовать CASE в таблице A, и я должен объединить таблицу A с таблицей B, которая изменяется.

Короче говоря, я хочу объединить таблицу A с таблицей B с учетом интервалов.

Если вы дадите мне правильный совет, я действительно ценю это.

(Я использую СУБД Oracle)

Комментарии:

1. На каких условиях таблицы соединяются? И не используйте строки для даты / времени, а соответствующий тип даты / времени. То же самое относится и к аналогу для целых чисел / чисел.

Ответ №1:

Я полагаю, вы немного сбили нас с толку, назвав свою колонку дат INTERVAL 🙂 Похоже, что это должна быть дата начала периода, и вы хотите объединить каждое имя с соответствующим периодом, то есть с последней датой начала перед датой имени.

Вы можете использовать CROSS APPLY в сочетании с FETCH FIRST ROW для этого:

 WITH a AS 
(
  SELECT 'KIM' AS name, DATE '2016-05-03' AS dt FROM DUAL
  UNION ALL
  SELECT 'LEE' AS name, DATE '2016-03-07' AS dt FROM DUAL
  UNION ALL
  SELECT 'PARK' AS name, DATE '2017-07-28' AS dt FROM DUAL
)
, b AS
(
  SELECT DATE '2016-02-27' AS start_dt, 1 AS num FROM DUAL
  UNION ALL
  SELECT DATE '2016-05-20' AS start_dt, 2 AS num FROM DUAL
  UNION ALL
  SELECT DATE '2017-08-25' AS start_dt, 3 AS num FROM DUAL
)
select *
from a 
cross apply
(
  select *
  from b
  where b.start_dt <= a.dt
  order by b.start_dt desc
  fetch first row only
);
 

Демо-версия: https://dbfiddle.uk/?rdbms=oracle_18amp;fiddle=db7f96b6ef82bfe985a9f894c2e30b82

Комментарии:

1. Я не знал «перекрестного применения» и «выборки». Я пытаюсь привыкнуть к использованию этих двух вещей. Спасибо