To jest ta rzecz. Mam te dwa stoły:

Tabela A:

id    col1    date_x
A     xxxx    2020-02-02
B     yyyy    2020-02-02
C     zzzz    2020-02-02

Tabela B.

id    col2    date_y
A     yyyy    2020-01-02
A     yyyy    2020-02-02
A     yyyy    2020-03-02

Chciałem przynieść COL2, gdy data_y jest najwyższa możliwa, ale musi być niższa niż data_x.

Oto, co zrobiłem:

select *,
         (select
                 top 1 col2
                     from table_B
                       where table_B.date_y < a.date_x and
                        table_B.id = a.id) as col2                   
 from table_A a

Teraz chciałem również przynieść DATA_Y, aby zrobić walidacja.

Jaki jest najlepszy sposób na to? Myślałem o tworzeniu innego (wybierz najlepsze 1 ...), ale wydaje się to bardzo nieefektywne. Kolejne połączenie byłoby również nieefektywne.

0
Dumb ML 23 lipiec 2020, 15:11

2 odpowiedzi

Najlepsza odpowiedź

Możesz dołączyć do tabel w warunkach i użyć MAX() i FIRST_VALUE() Funkcje okna, aby uzyskać wartości date_y i col2:

select distinct a.*,
       first_value(b.col2) over (partition by a.id order by b.date_y desc, b.col2) col2,
       max(b.date_y) over (partition by a.id) date_y
from tableA a left join tableB b
on b.id = a.id and b.date_y < a.date_x

Możesz zmienić LEFT dołącz do INNER dołącz, jeśli chcesz tylko dopasowane wiersze z 2 tabel.
Zobacz Demo.

1
forpas 23 lipiec 2020, 12:46

Twoje podejście za pomocą skorelowanego podzapytania jest OK - i wsporniki redShift top (Chociaż wolę limit, który jest bardziej wspierany w innych bazach danych).

Jednak brakuje klauzuli order by w podzapytaniu - bez niego otrzymujesz nieprzewidywalny wiersz z tych, które spełniają klauzulę where, która nie jest tym, czego chcesz.

Chciałbym polecić:

select 
    a.*,
    (
        select col2
        from table_B b
        where b.date_y < a.date_x and b.id = a.id
        order by b.date_y desc
        limit 1
    ) as col2                   
 from table_A a

W przypadku wydajności rozważ indeks na table_B(id, date_y, col2).

0
GMB 23 lipiec 2020, 13:05