Объединение таблиц - сопоставление числа с частью списка чисел, разделенных запятыми - PullRequest
0 голосов
/ 23 апреля 2019

Я пытаюсь написать SQL-запрос, объединяющий две таблицы: «Праздники», содержащие подробности о праздничных пакетах, и «Полеты», содержащие сведения о рейсе.Пожалуйста, найдите упрощенную выдержку из обеих таблиц ниже.

Праздники:

Destination       Departure            Duration               Board_Type
    CFU              GLA                   7                     Full
    ATH              MAN                   14                    Half
    ZTH              BRS                   10                    Full

Авиабилеты:

Flight Num      Destination    Departure    Duration_Switch     Duration
   2490             CFU          EDI              IN            7,8,10,11
   2491             HER          LHR              IN               9
   2492             ATH          LTN            NOT IN            10,14

Я пытаюсь присоединиться к этим таблицам по ряду критериев, включая продолжительность отпуска.В Праздники, Длительность просто дает мне длину этого конкретного пакета.Таблица «Полеты» более сложна - если для параметра duration_switch установлено значение «IN», то в поле «Длительность» отображается список продолжительности выходных для этого рейса.Если duration_switch 'NOT IN', то Duration отображает список длительностей выходных, НЕ путешествующих на этом рейсе.

Я пытаюсь создать условие JOIN так, чтобы, если f.duration_switch был 'IN', таблицыприсоединиться, если продолжительность праздника указана в списке продолжительности полета или если f.duration_switch имеет значение «NOT IN», то список продолжительности полета.Если значение duration_switch равно NULL, это означает, что все продолжительности обслуживаются этим рейсом, поэтому я также хочу присоединиться к ним.

Я попробовал следующее:

    SELECT *
      FROM holidays h
RIGHT JOIN flights  f
        ON h.destination = f.destination
       AND h.departure   = f.departure
       AND ((f.duration_operator = 'IN' AND f.duration LIKE '%'||h.duration||'%') 
        OR (f.duration_operator = 'NOT IN' AND f.duration NOT LIKE '%'||h.duration||'%') 
        OR f.duration_operator IS NULL)

Проблема с этим кодомявляется то, что, например, если h.Duration равен 4, это будет соответствовать j.Duration, скажем, 10,11,14, потому что он содержит цифру 4.

1 Ответ

1 голос
/ 23 апреля 2019

Как я уже сказал (в качестве комментария), отправленные вами образцы данных несколько неверны , поскольку нет совпадений по вылетам, поэтому - независимо от того, что вы напишете позже, это условие не приводит к извлечению строк.

Вот почему я немного изменил пример данных;взгляните на следующий код, посмотрите, имеет ли он смысл.Идея такова: разбить duration (который хранится в виде списка значений, разделенных запятыми) на строки, чтобы вы могли присоединить его к duration в другой таблице.

Я не знаю, что duration_operator есть;в примерах данных нет ни одного.

Вот так:

SQL> with
  2  holidays (destination, departure, duration) as
  3    (select 'CFU', 'GLA', 7  from dual union all
  4     select 'ATH', 'LTN', 14 from dual union all
  5     select 'ZTH', 'BRS', 10 from dual
  6    ),
  7  flights (flight_num, destination, departure, duration_switch, duration) as
  8    (select 2490, 'CFU', 'GLA', 'IN'    , '7,8,10,11' from dual union all
  9     select 2491, 'HER', 'LHR', 'IN'    , '9'         from dual union all
 10     select 2492, 'ATH', 'LTN', 'NOT IN', '10,14'     from dual
 11    ),
 12  --
 13  -- split all DURATIONs from FLIGHTS to rows, so that you could join them with HOLIDAYS
 14  flisplit as
 15    (select flight_num,
 16            destination,
 17            departure,
 18            duration_switch,
 19            regexp_substr(duration, '[^,]+', 1, column_value) duration
 20     from flights join
 21          table(cast(multiset(select level from dual
 22                              connect by level <= regexp_count(duration, ',') + 1
 23                             ) as sys.odcinumberlist )) on 1 = 1
 24    )
 25  select f.flight_num,
 26         h.destination,
 27         h.departure,
 28         h.duration,
 29         f.duration_switch
 30  from holidays h join flisplit f on h.destination = f.destination
 31                                 and h.departure   = f.departure
 32      and (   h.duration =  case when duration_switch = 'IN' then f.duration end
 33           or h.duration <> case when duration_switch = 'NOT IN' then f.duration end
 34          );

FLIGHT_NUM DES DEP   DURATION DURATI
---------- --- --- ---------- ------
      2490 CFU GLA          7 IN
      2492 ATH LTN         14 NOT IN

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...