[Firebird] złączenie czterech tabel

0

Witam,
Mam cztery tabele: tab_user, tab_segregator, tab_plik i tab_uprawnienia.
struktura tabel:
#tab_user: id, imię, nazwisko;
#tab_segregator: id, nazwa, id_pliku;
#tab_plik: id, nazwa_pliku;
#tab_uprawnienia: id, id_user, id_segregator, id_plik, u1, u2, u3, typ;

W tab_uprawnienia, w polach [u1],[u2],[u3] zapisywane są uprawnienia w postaci 'TAK' lub 'NIE'. W polu [typ] natomiast: 1, 2 lub 3.
Istnieją trzy możliwości zapisów w tab_uprawnienia:

LP | id_user | id_seg | id_plik | typ
1 | 1 | null | null | 1
2 | 1 | 1 | null | 2
3 | 1 | 1 | 1 | 3

wiersz 1: uprawnienia domyślne danego użytkownika;
wiersz 2: uprawnienia danego użytkownika do danego segregatora i domyślne do plików w określonym segregatorze;
wiersz 3: uprawnienia danego użytkownika do określonego pliku w określonym segregatorze.

I teraz pytanie dotyczące sytuacji 2 i 3:
Jak pobrać spis uprawnień wszystkich użytkowników do wszystkich plików z tabeli [tab_pliki] przypisanych do określonego segregatora, bez względu na to, czy określono id_pliku czy nie?

Do tej pory robiłem to w programie: najpierw - w jednym zapytaniu - pobierałem spis wszystkich plików, potem w pętli pobierałem uprawnienia do pliku (jeśli istnieje typ=3, pobierz uprawnienia z typ=3, jeśli nie istnieje typ=3, pobierz typ=2), i dane z wynikami wrzucałem do raportu.

Teraz, mój kochany szef, zobowiązał mnie, bym dostarczył mu jedno zapytanie, żeby mógł robić sobie raporty w IBExpert.

Będę wdzięczny za odpowiedź.

Pozdrawiam
Tomasz M.

0
  1. struktura zła!
    tab_segregator - źle, pownno być: id, nazwa
    tab_plik - źle, powinno być: id, nazwa, id_seg
    bo zakładam że dany plik może być tylko w jednym segregatorze

tab_uprawnienia - nie wiem co oznaczają pola u1, u2, u3 oraz przede wszystkim typ. Jak to się stopniuje? czyli jak masz taki przykład jak w tabelce, to uprawnienia jakoś się sumują/nakładają, czy zawsze najważniejsze jest najbardziej szczegółowe, czyli to dla konkretnego id_seg i id_plik?

0
O-to-to napisał(a):
  1. struktura zła!
    tab_segregator - źle, pownno być: id, nazwa
    tab_plik - źle, powinno być: id, nazwa, id_seg
    bo zakładam że dany plik może być tylko w jednym segregatorze

tab_uprawnienia - nie wiem co oznaczają pola u1, u2, u3 oraz przede wszystkim typ. Jak to się stopniuje? czyli jak masz taki przykład jak w tabelce, to uprawnienia jakoś się sumują/nakładają, czy zawsze najważniejsze jest najbardziej szczegółowe, czyli to dla konkretnego id_seg i id_plik?

Na tej bazie danych działa program firmy trzeciej. Nie wiem, jakich zapytań używa ten program. Nie mam dostępu do kodu źródłowego.

[tab_uprawnienia] posiada więcej pól z uprawnieniami - do u31. czego dotyczą pozostałe? Nie wiem, to nie istotne, mnie interesują tylko u1, u2 i u3.
[tab_pliki] posiada więcej pół określających dany plik: data utworzenia, data edycji, itp;

pliki zawarte w [tab_pliki] mogą być przydzielone do różnych segregatorów, stąd struktura tabeli [tab_segregator]: id, nazwa, id_pliku i [tab_pliki]:id, nazwa_pliku.
pola w [tab_uprawnienia]: u1: dostęp do danego segregatora, u2: plik widoczny dla określonego użytkownika, u3: dostęp do pliku dla określonego użytkownika.
Najważniejsze są zawsze uprawnienia z typ=3. Powinno to wyglądać tak, że:

  1. wyświetl uprawnienia z typ=3;
  2. jeśli nie ma typ=3 to wyświetl typ=2;
    Zawsze uprawnienie najbardziej szczegółowe jest najważniejsze.

Złączenie trzech tabel: [tab_seg], [tab_pliki] działa poprawnie.
mogę podzielić [tab_seg] na:

  1. [kart_seg]: id, nazwa;
  2. [tab_seg_pliki]: id, id_seg, id_plik;
    tylko nie wiem, czy to coś zmieni.
0

Oczywiście że zmieni!
tab_seg_plik - pole id w niej jest zbędne, gdyż kluczem powinno być id_seg + id_plik
bez tej tabeli jeśli w segregatorze 1 bezie plik 1, 2, a w seg 2 bedzie 2 i 3 to:

tab_seg
id_seg, nazwa, id_plik
1, seg1, 1
1, seg1, 2
2, seg2, 2
2, a-dlaczego-nie-dac-tu-innej-nazwy-niz-seg2-???, 3

0
O-to-to napisał(a):

Oczywiście że zmieni!
tab_seg_plik - pole id w niej jest zbędne, gdyż kluczem powinno być id_seg + id_plik
bez tej tabeli jeśli w segregatorze 1 bezie plik 1, 2, a w seg 2 bedzie 2 i 3 to:

tab_seg
id_seg, nazwa, id_plik
1, seg1, 1
1, seg1, 2
2, seg2, 2
2, a-dlaczego-nie-dac-tu-innej-nazwy-niz-seg2-???, 3

Problemem nie jest struktura i powiązanie tabel: [tab_pliki] i [tab_seg]. rozwiązałem to poprzez GROUP BY, ale masz rację zmienię to. Będę musiał utworzyć nowe tabele i w wyzwalaczach kopiować do nowych tabel. Nie mogę tak mocno ingerować w strukturę bazy.

problemem jest pobranie danych ze złączenia tabel: [tab_pliki], [tab_seg] i [tab_uprawnienia]+[tab_uzytk]

0

Rozwiązanie z CTE tak na szybko
dla określonego segregatora (@seg) odpowiednio sortuje uprawnienia tak, aby dla każdego pliku w segregatorze użyć tego najwłaściwszego wiersza z uprawnieniami
pewnie można coś ułatwić, ale nie chce mie się nad tym więcej siedzieć, mam nadzieję że nic nie pomyliłem, jeśli coś pomyliłem daj znać


;with TU
as
(
select id_user, id_plik, u1, u2, u3, typ
from
(
    select 
        row_number() over (partition by id_user, id_plik order by typ desc, id_seg desc, id_plik desc) as rn,
        *   
    from @tab_uprawnienia
    where id_seg = @seg or id_seg is null
) as t
where rn = 1
)
select * from @tab_user u
inner join
(
    select id_user, id_plik, nazwa, u1, u2, u3 from
    (
        select 
            row_number() over (partition by tu.id_user, p.id order by typ desc) as rn,
            tu.id_user, p.id [id_plik], p.nazwa, tu.u1, tu.u2, tu.u3, tu.typ
        from
        (select * from @tab_segregator where id = @seg) as sf
        inner join @tab_plik p on sf.id_plik = p.id
        left join TU tu on p.id = tu.id_plik or tu.id_plik is null
    ) as t
    where rn = 1    
) as t on u.id = t.id_user

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