Mam 2 struktury tabel:

TAB_1 ( TRN_ID , STN_CODE,DIST_FRM_SRC)    

TAB_2 ( TRN_ID , SRC_STN , DSTN_STN ) 

Dane w TAB_1:

enter image description here

Dane w TAB_2

enter image description here

Muszę pobrać wszystkie wiersze z TAB_1 Odpowiadające SRC_STN i DST_STN w TAB_2, więc OP będzie

enter image description here

Proszę o przewodnik.

-1
radha 3 kwiecień 2020, 12:42

4 odpowiedzi

Najlepsza odpowiedź

Wygląda na proste sprzężenie:

SQL> with
  2  tab_1 (trn_id, stn_code, dist_frm_src) as
  3    (select 100, 'GHU', 0 from dual union all
  4     select 100, 'SDP', 2 from dual union all
  5     select 100, 'DRK', 5 from dual union all
  6     select 100, 'SAB', 7 from dual union all
  7     select 100, 'DRT', 8 from dual union all
  8     select 100, 'POL', 10 from dual union all
  9     select 100, 'WRT', 15 from dual),
 10  tab_2 (trn_id, src_stn, dstn_stn) as
 11    (select 100, 'SDP', 'POL' from dual),
 12  --
 13  dfs as
 14    (select x.trn_id,
 15            a.dist_frm_src val_1,
 16            b.dist_frm_src val_2
 17     from tab_2 x join tab_1 a on x.trn_id = a.trn_id and x.src_stn = a.stn_code
 18                  join tab_1 b on x.trn_id = b.trn_id and x.dstn_stn = b.stn_code
 19    )
 20  select a.trn_id, a.stn_code, a.dist_frm_src
 21  from tab_1 a join dfs d on a.trn_id = d.trn_id
 22                         and a.dist_frm_src between d.val_1 and d.val_2
 23  order by trn_id, a.dist_frm_src;

    TRN_ID STN DIST_FRM_SRC
---------- --- ------------
       100 SDP            2
       100 DRK            5
       100 SAB            7
       100 DRT            8
       100 POL           10

SQL>
1
Littlefoot 3 kwiecień 2020, 10:29

Możesz join:

select t1.*
from tab_1 t1
inner join tab_2 t2 
    on t1.trnid = t2.trnid and t1.stn_code between t2.src_stn and t2.dstn_stn

Inna opcja wykorzystuje not exists; jest to przydatne, jeśli przedziały mogą się nakładać w tab_2:

select t1.*
from tab_1 t1
where exists (
    select 1 
    from tab_2 t2 
    where t1.trnid = t2.trnid and t1.stn_code between t2.src_stn and t2.dstn_stn
)
0
GMB 3 kwiecień 2020, 09:48

Użyj prostego łączenia z funkcjami okna:

select t12.TRN_ID, t12.STN_CODE, t12.DIST_FRM_SRC
from (select t2.*,
             min(case when t1.stn_code = t2.src_stn then dist_frm_src end) as first_dist_frm_src,
             max(case when t1.stn_code = t2.dst_stn then dist_frm_src end) as last_dist_frm_src
      from tab_1 t1 join
           tab_2 t2
           on t1.trn_id = t2.trn_id
     ) t12
where t12.dist_fm_src between first_dist_frm_src and last_dist_frm_src;
0
Gordon Linoff 3 kwiecień 2020, 11:15

Należy wziąć pod uwagę część całkowitą z kodów stacji, które mają typ danych VARCHAR2 , a następnie pobrać dane między liczbami całkowitymi.

Ponieważ kody stacji mają prefiks S, użyłem LTRIM , aby go przyciąć i przekonwertować ciąg na liczbę za pomocą TO_NUMBER :

SELECT
    t1.trn_id, t1.stn_code, t1.dist_frm_src
FROM
    tab_1   t1
    JOIN tab_2   t2 
    ON t1.trn_id = t2.trn_id
WHERE
    to_number(ltrim(t1.stn_code, 'S'))
    BETWEEN to_number(ltrim(t1.src_stn, 'S')) 
    AND     to_number(ltrim(t1.dstn_stn, 'S'))
ORDER BY t1.trn_id, t1.stn_code;
1
Lalit Kumar B 3 kwiecień 2020, 10:07