Temat: Złączenie kilku tabel
Witam
Jak w postgresie wykonać podobne złączenie, pewnie jakiś zagnieżdżony join, ale nie wiem jak to ugryźć
Przykład z Oracle:
k.num(+)=r.num and
k.o(+)=r.o
PostgreSQL to najbardziej zaawansowany system relacyjnych baz danych Open Source.
Nie jesteś zalogowany. Proszę się zalogować lub zarejestrować.
Zaloguj się lub zarejestruj by napisać odpowiedź
Witam
Jak w postgresie wykonać podobne złączenie, pewnie jakiś zagnieżdżony join, ale nie wiem jak to ugryźć
Przykład z Oracle:
k.num(+)=r.num and
k.o(+)=r.o
To sa outer joiny (wystepujace tez w oracle), tylko nie pamietam czy te orcalowe plusiki to byly right outer join czy left outer join .
Narazie nic nie łączę, ale przenoszę kilka tabel z Oracle i jeżeli zajdzie potrzeba wykonania raportu takiego jak był w Oracle to chciałbym wiedzieć jak to zrobić.
Left i Right Outer juz sprawdziłem dla dwóch tabel, ale nie wiem jak to zastosować dla trzech tabel gdzie np: dwie odwołują się do jednej
t1.rok(+)=t2.rok and
t1.rok(+)=t3.rok
Np: tabela t1 przechowuje wszystkie nr_zlecenia i np: daty utworzenia zlecenia, tabela t2 przechowuje zadania do tego zlecenia wraz z numerem zlecenia, tabela t3 przechowuje materiały dla tego zlecenia wraz z numerem zlecenia
Ja potrzebuje wszystkie nr_zlecenia, data_zlecenia z tabeli t1nawet jeżeli jeszcze nie ma dla nich wpisu w zadaniach i materiałach + nazwe zadania z t2 i materiał z t3
where
t1.nr_zlecenia(+)=t2.nr_zlecenia and
t1.nr_zlecenia(+)=t3.nr_zlecenia
Jezeli masz warunek wyboru to masz najwazniejsza i najistotniejsza czesc zapytania; operacje zlaczenia nie maja tu "wielkiego" znaczenia; kazde zapytanie jest podzbiorem iloczynu kartezjansiego tabel wiec moze polaczysz je sobie w ten sposob;
Jak tu dorzucić trzecią tabele, nazwa pola i tabeli nieistotna, chciałbym tylko zobaczyć odwołanie do trzeciej tabeli, jeżeli to w ogóle możliwe.
select godz_planowane,wydz_w_zad,rok,miesiac,
wydzial,robotnicze,nierobotnicze
from tbl_godz_z_planowania
left join tbl_stan_zatrudnienia on wydz_w_zad=wydzial
W domu nie mam tabel ale mniej więcej jest to tak
Tabela tb_godz_z_planowania
wydz_w_zad rok miesiac godz_planowane
AA 2009 2 123
AB 2009 2 321
AX 2009 3 111
AB 2009 4 222
Tabela tbl_stan_zatrudnienia
wydzial robotnicze nierobotnicze
AA 11 22
AX 33 22
AB 21 12
Uzyskuje taki wynik
wydz_w_zad rok miesiac godz_planowane wydzial robotnicze nierobotnicze
AA 2009 2 123 AA 11 22
AB 2009 2 321 AB 21 12
AX 2009 3 111 AX 33 22
AB 2009 4 222 AB 21 12
Pomijam że wydział sie powtarza w wyniku, ale zaciągneły mi sie wszystkie rekordy z pierwszej tabeli i dopisały do nich odpowiednie z drugiej.
Trzeciej tabeli nie mam, dlatego pytam czysto teoretycznie jak można by ja podłączyc do zapytania aby końcowa tabela zawierała kolumny również z trzecej tabel i rekordy dopasowane do pierwszej tabeli. Nie wiem czy sie jasno wyraziłem. może założe że trzecia tabela była by np taka:
tbl_trzecia
wydzial kierownik budynek
AA Janek c12
AB Stefan bt6
AX Leon p23
i tak sobie mysle że tabela końcowa mogła by wyglądać tak
wydz_w_zad rok miesiac godz_planowane wydzial robotnicze nierobotnicze wydzial kierownik budynek
AA 2009 2 123 AA 11 22 AA Janek c12
AB 2009 2 321 AB 21 12 AB Stefan bt6
AX 2009 3 111 AX 33 22 AX Leon p23
AB 2009 4 222 AB 21 12 AB Stefan bt6
Powielam wydział, ale tylko dla rozjaśnienia że jest on łącznikiem wszystkich tabel
Może nie wygląda to pięknie, ale czasem takie dane są potrzebne jeżeli "zlecający" tak chce i już. Prosiłbym o nie odnoszenie sie do sensu czy to jest dobrze czy źle tylko jak uzyskac taki efekt.
from tbl_godz_z_planowania
left join tbl_stan_zatrudnienia on wydz_w_zad=wydzial
pozwala mi uzyskac pierwszą część wyniku, a jak odnieśc się do tbl_trzecia?? Mam nadzieję że nie nagmatwałem.
Tylko w tabeli pierwszej wydziały się powtarzają
Ostatnio edytowany przez adamleon (2009-09-04 20:03:12)
Witam,
popraw prosze ponizszy skrypt jezeli sa jakies uwagi i przede wszystkim wskaz klucz podstawowy;
CREATE TABLE tb_godz_z_planowania
(
wydz_w_zad CHAR(2),
rok CHAR(4),
miesiac CHAR (2),
godz_planowane CHAR(3)
);
INSERT INTO tb_godz_z_planowania
VALUES ('AA', '2009', '2', '123')
INSERT INTO tb_godz_z_planowania
VALUES('AB', '2009', '2', '321')
INSERT INTO tb_godz_z_planowania
VALUES('AX', '2009', '3', '111')
INSERT INTO tb_godz_z_planowania
VALUES('AB', '2009', '4', '222')
;
Mam taka tabelę, nie mam tu klucza podstawowego ponieważ nie mam tu unikatowego pola które było by mi potrzebne. Dane w tej tabeli są kasowane i importowane co jakiś czas i powtarzają się w rekordach. W pozostałych tabelach mogę przyjąć wydział jako klucz ponieważ tam rekordy nie powtarzaja się.
CREATE TABLE "tbl_godz_z_planowania" (
"rok" SMALLINT,
"miesiac" SMALLINT,
"godz_planowane" NUMERIC(8,2),
"wydz_w_zad" VARCHAR(10)
) WITH OIDS;
Chodzi mi o to że np:
where tab1.wydzial=tab2.wydzial and tab1.wydzial=tab3.wydzial
da mi tylko rekordy gdzie wydziały w tych tabelach są takie same, a jeżeli w tab1 mam więcej wydziałów niż w tab2 i tab 3 to już mi ich nie pokaże. Jak wybrać wszystkie z tab1 nawet jeżeli nie mają odpowiedników w pozostałych tabelach.
Moja tab1 to =>> tbl_godz_z_planowania tu różnych wydziałów jest więcej niż w pozostałych tabelach i dla tych wydziałów
kolumny w doniesieniu do wcześniejszego przykładu powinny być puste:
wydz_w_zad rok miesiac godz_planowane wydzial robotnicze nierobotnicze wydzial kierownik budynek
ZZ 1999 11 321
AA 2009 2 123 AA 11 22 AA Janek 2
KK 2000 01 777
Ostatnio edytowany przez sulavix (2009-09-07 11:30:42)
mam tak:
CREATE TABLE "tbl_stan_zatrudnienia" (
"wydzial" VARCHAR(10),
"robotnicze" SMALLINT,
"nierobotnicze" SMALLINT
) WITH OIDS;
OIDS samo się dodaje, tabele tworzę jak i całą resztę w EMS SQL Manager
Wynik się zgadza, może wyjde w przód, ale pokazuje tylko te rekordy które są równe, ale tych które są w tabeli tbl_godz_z_planowania, a nie ma w tbl_stan_zatrudnienia nie pokaże i tu jest sprawa jasna. Left Join by je pokazał, ale mnie zależy na 3 tabelach jednocześnie. Może się powtarzam, ale chciałbym żebyśmy się zrozumieli.
CREATE TABLE "tbl_wydz_kierownik" (
"wydzial" VARCHAR(10),
"kierownik" VARCHAR(20),
"budynek" VARCHAR(10)
) WITH OIDS;
CREATE TABLE "tbl_godz_z_planowania"
(
"wydz_w_zad" VARCHAR(10),
"rok" SMALLINT,
"miesiac" SMALLINT,
"godz_planowane" NUMERIC(8,2)
);
INSERT INTO tbl_godz_z_planowania
VALUES ('AA', 2009, 2, 123)
INSERT INTO tbl_godz_z_planowania
VALUES('AB', 2009, 2, 321)
INSERT INTO tbl_godz_z_planowania
VALUES('AX', 2009, 3, 111)
INSERT INTO tbl_godz_z_planowania
VALUES('AB', 2009, 4, 222)
;
CREATE TABLE "tbl_stan_zatrudnienia"
(
"wydzial" VARCHAR(10),
"robotnicze" SMALLINT,
"nierobotnicze" SMALLINT
);
INSERT INTO tbl_stan_zatrudnienia
VALUES('AA', 11, 22)
INSERT INTO tbl_stan_zatrudnienia
VALUES('AX', 33, 22)
INSERT INTO tbl_stan_zatrudnienia
VALUES('AB', 21, 12);
CREATE TABLE "tbl_wydz_kierownik"
(
"wydzial3" VARCHAR(10),
"kierownik" VARCHAR(20),
"budynek" VARCHAR(10)
);
INSERT INTO tbl_wydz_kierownik
VALUES('AA', 'Janek', 'c12')
INSERT INTO tbl_wydz_kierownik
VALUES('AB', 'Stefan', 'bt6')
INSERT INTO tbl_wydz_kierownik
VALUES('AX', 'Leon', 'p23')
;
Nie wiem czy to końcowy etap, ale nie działa
jeszcze mniej rekordów niż we wcześniejszych zapytaniach
potrzebuje taki wynik
wydz_w_zad rok miesiac godz_planowane wydzial robotnicze nierobotnicze wydzial kierownik budynek
ZZ 1999 11 321
AA 2009 2 123 AA 11 22 AA Janek 2
KK 2000 01 777
WW 2009 32 1211 WW 21 32
TT 2008 11 444 TT kierownikTT Z21
wszystko z tbl_godz_z_planowania i jeżeli są to odpowiadające im rekordy z dwóch pozostałych tabel
1 rekord nie ma nic z tabeli 2 i 3
2 rekord ma wszystko
3 rekord nie ma nic z tabeli 2 i 3
4 rekord nie ma nic z tabeli 3
5 rekord nie ma nic z tabeli 2
Ostatnio edytowany przez adamleon (2009-09-07 14:43:50)
Może szpecem od baz nie jestem, ale jak podałem wcześniej w przykładzie moim z 13:43:18 jest 5 rekordów. Jeżeli myślisz o swoim przykładzie z 13:28:56to dopiero teraz go zauważyłem, nie mam pojecia dlaczego mi to umknęło - przepraszam, ale w pracy mogłem rozpocząć pisanie wcześniej przed Twoja wiadomościa, a wysłać po Tobie (zamęt w pracy).
Wcześniej miałem doczynienia z Accessem, wiem co to klucze, not null itd,jednak jak pisałem wczesniej nie chciałbym krytyki że tabele są takie czy inne, są one przykładowe, a mnie chodzi o uzyskanie wyniku, a to czy jest not null czy nie w tej chwili wydaje mi sie nia ma znaczenia. Moze poczekam jak ktoś inny spojrzy na to wszystko z boku, ale dzięki za chęci i cierpliwość.
Co prawda nie jestem może w temacie (strasznie długa ta dyskusja ) ale może tak zadziała
select * from tbl_godz_z_planowania left join
(select foo1.wydzial as w1, * from tbl_stan_zatrudnienia foo1, tbl_wydz_kierownik foo2 where
foo1.wydzial=foo2.wydzial) foo3
on (wydz_w_zad=foo3.w1);
Z lenistwa dodałem powieliłem jedną kolumnę
foo1.wydzial as w1
bo w left join nie mozna napisac
on (wydz_w_zad=wydzial);
bo select wewnetrzny ma dwie kolumny o nazwie wydzial. Wiec albo zmienisz nazwy w kolumn aby sie nie powtarzaly w różnych tabelach, albo po selecie zamiast * wymenisz kolumny i je zaliasujesz. Ja dodałem jedną nadmiarowo bo z reguły leniwy jestem i nie chciało mi sie wymieniać (wolałem wpisać *).
Ogólnie rzecz biorąc powinno działać jak się nie walnąłem przy przepisywaniu zapytania z wirtualki.
Z tego co zrozumiałem pomiędzy tbl_stan_zatrudnienia i tbl_wydz_kierownik ma być inner join.
Wszystko pewnie można uprościć tylko do join'ów ale ja ich tak nie lubię .
Witam
Prawie działa, pokazuje wszystkie rekordy z tbl_godz_z_planowania, ale z 2 i 3 tabeli tylko te które są równe np:
wydz_w_zad rok miesiac godz_planowane wydzial robotnicze nierobotnicze wydzial kierownik budynek
ZZ 1999 11 321
AA 2009 2 123 AA 11 22 AA Janek 2
KK 2000 01 777
WW 2009 32 1211 WW 21 32 WW Józek B12
TT 2008 11 444
Jeżeli w tbl_stan_zatrudnienia mam wydziały których nie ma w tbl_wydz_kierownik to już ich nie pokazuje.
To i tak już coś. Kiedy znajdę chwilę i rozwiążę problem to napiszę.
Dzięki
Posty [ 1 do 25 z 39 ]
Zaloguj się lub zarejestruj by napisać odpowiedź
[ Wygenerowano w 0.014 sekund, wykonano 10 zapytań ]