Połączenie wiele do wielu

0

Witam,
Mam dwie tabele
osoby
id_osoby    data_poczatkowa    data_koncowa    imie    nazwisko
10    2015-01-01    2015-01-31    Jan     Kowalski
10    2015-02-01    2015-02-28    Jan     Kowalski
10    2015-03-01    2015-03-31    Jan     Kowalski
15    2015-01-02    2015-01-31    Piotr    Nowak
15    2015-02-02    2015-02-28    Piotr    Nowak
15    2015-03-02    2015-03-31    Piotr    Nowak

oraz
kwoty

id_ew id_osoby kwota miesiac
1 10 5000 02
2 10 6000 03
3 10 7000 04
4 10 8000 05
5 15 7000 02
6 15 7010 03
7 15 7020 04
8 15 7030 05
9 15 7040 06

Chciałbym uzyskać tabelę wynikową w której będą dane Jana Kowalskiego oraz Nowaka z datą ważności z lutego i jego wpłatę z lutego. Klucz w tabeli osoby to id_osoby+data_poczatkowa w tabeli kwoty id_ew

czyli

id_osoby data_poczatkowa data_koncowa nazwisko imię kwota miesiac
10 2015-02-01 2015-02-28 Kowalski Jan 5000 02
15 2015-02-01 2015-02-28 Nowak Piotr 7000 02

Dziękuję za pomoc
i pozdrawiam Paweł

1
  1. Jezeli masz taka mozliwosc rozwaz przeprojektowanie bazy.
  2. Rozumiem, ze drugi wynik powinien zawierac date poczatkowa 2015-02-02 a nie 2015-02-01?
  3. Proponowalbym liczyc sume wplat w danym miesiacu poniewaz zawsze ktos moze niechcacy wplacic za malo i doplacic kolejnym przelewem.
  4. Nie podales dialektu, wiec wybralem sobie baze PostgreSQL. Sprobuj czegos takiego
select o.id_osoby, o.data_poczatkowa, o.data_koncowa, o.nazwisko, o.imie, sum(k.kwota), k.miesiac 
from osoby o
left join kwoty k on o.id_osoby=k.id_osoby
where date_part('month', o.data_poczatkowa)=2 and k.miesiac=2
group by o.id_osoby, o.data_poczatkowa, o.data_koncowa, o.nazwisko, o.imie, k.miesiac

Powyzsze zapytanie zwrocilo poprawny wynik (przy zalozeniu, ze machnales sie w dacie). Moze sie jednak okazac, ze wymaga jakis poprawek - bedziesz o tym wiedzial testujac na wiekszej liczbie rekordow.

Szczególnie uważałbym tutaj na sytuacje typu "data_poczatkowa / data koncowa wystepuje dwa razy w tym samym miesiacu".

0

TK dziękuję za sugestie, niestety nie wyraziłem się precyzyjnie.
ad.1 Niestety nie mogę przeprojektować tabel, bo to stan zastany i zmiany nie są niedopuszczalne:(.
ad.2 Nie jest pomyłką data. Tabela osoby w swojej zawartości ma również historię danych. Czyli zakładamy sytuację, że Kowalski 14 lutego zmieni nazwisko na Kowalski-Jaworski . W tabeli pojawi się rekord
10 2015-02-01 2015-02-13 Jan Kowalski
10 2015-02-14 2015-02-28 Jan Kowalski-Jaworski

Zapytanie powinno uwzględniać zakres ważności dat.

Gdy będę chciał wybrać dane z 11 lutego dla tej osoby powinienem dostać wynik
id_osoby data_poczatkowa data_koncowa nazwisko imię kwota miesiac
10 2015-02-01 2015-02-13 Kowalski Jan 5000 02

a na 19 lutego
id_osoby data_poczatkowa data_koncowa nazwisko imię kwota miesiac
10 2015-02-14 2015-02-28 Kowalski-Jaworski Jan 5000 02

ad.3 Oczywiście suma jest wskazana

ad.4 Baza danych Oracle

pozdr
Paweł

1

Cześć,

Jeżeli masz dokładną całą datę(Rok, Miesiąc, Dzień), to możesz zrobić to tak:

SELECT o.id_osoby, o.data_poczatkowa, o.data_koncowa, o.nazwisko, o.imie, SUM(k.kwota), k.miesiac 
FROM osoby o
LEFT JOIN kwoty k ON o.id_osoby=k.id_osoby
WHERE o.data_poczatkowa<='tutaj wpisz Twoją datę' and o.data_koncowa >='tutaj wpisz Twoją datę' 
GROUP BY o.id_osoby, o.data_poczatkowa, o.data_koncowa, o.nazwisko, o.imie, k.miesiac

Jeżeli chcesz też wpłaty w oparciu o sam miesiąc, dzień bez roku-napisz to stworzymy odpowiednie zapytania.

Pozdrawiam

EDIT:Jest to lekko zmienione zapytanie @tk, żeby nie było, że kopiuje i się nie przyznaje;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1