Klucz główny jako klucz obcy w dwóch tabelach

Użytkowanie programu bazodanowego
forami
Posty: 2
Rejestracja: pn lut 02, 2015 7:57 pm

Klucz główny jako klucz obcy w dwóch tabelach

Post autor: forami »

Witam wszystkich. Mam 4 tabele:

- dostawcy
- klienci
- kraje
- transakcje


Każdy dostawca może być z jednego z krajów z tabeli kraje. Również kupujący może być z jednego z krajów z tab. kraje.

W tabeli "transakcje" zapisuję co to za towar, który dostawca i który kupujący.

Jak wyciągnąć kwerendą takie dane: nr transakcji, kraj dostawcy i kraj kupującego?

Czy konieczne będzie utworzenie oddzielnych tabel np. tab_KrajeDostawców i tab_KrajeKlientów?

W załączeniu baza danych.
Załączniki
Baza danych - przykładowa.odb
W pliku jest także kwerenda obrazująca moje pytanie dot. kwerendy.
(6.58 KiB) Pobrany 170 razy
LibreOffice Wersja: 4.2.7.2
Linux Kubuntu 14.04 LTS
Jan_J
Posty: 4626
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Klucz główny jako klucz obcy w dwóch tabelach

Post autor: Jan_J »

Czy konieczne będzie utworzenie oddzielnych tabel np. tab_KrajeDostawców i tab_KrajeKlientów?
Nie.
Jak wyciągnąć kwerendą takie dane: nr transakcji, kraj dostawcy i kraj kupującego?
Masz kilka metod

1. przez złączenie pełne z klauzulą WHERE

Kod: Zaznacz cały

select 
    id_transakcji as "numer transakcji", 
    k1.NazwaKraju as "kraj dostawcy", 
    k2.NazwaKraju as "kraj kupującego"
from 
    transakcje as "t", 
    dostawcy as "d", 
    kraje as "k1", 
    klienci as "k", 
    kraje as "k2"
where 
    t.idDostawcy = d.IDDostawcy 
    and d.idKrajLubRegion = k1.IDKraj
    and t.idKlienta = j.IDKlienta 
    and k.idKrajLubRegion = k2.IDKraj
Warto używać, jeśli baza na kompilator zapytań z dobrym optymalizatorem.

2. przez złączenie wewnętrzne z klauzulą ON

Kod: Zaznacz cały

select 
    id_transakcji as "numer transakcji", 
    k1.NazwaKraju as "kraj dostawcy", 
    k2.NazwaKraju as "kraj kupującego"
from 
    transakcje as "t" 
    join dostawcy as "d" on t.idDostawcy = d.IDDostawcy 
    join kraje as "k1" on d.idKrajLubRegion = k1.IDKraj
    join klienci as "k" on t.idKlienta = j.IDKlienta
    join kraje as "k2" on k.idKrajLubRegion = k2.IDKraj
Jest to postać bliska optymalnej, warto używać w bazach słabo optymalizujących zapytania.

3. przez złączenie wewnętrzne z klauzulą USING -- tylko wtedy, kiedy JOIN odbywa się przez dopasowanie jednakowo nazwanych atrybutów

Kod: Zaznacz cały

select 
    id_transakcji as "numer transakcji", 
    k1.NazwaKraju as "kraj dostawcy", 
    k2.NazwaKraju as "kraj kupującego"
from 
    transakcje as "t" 
    join dostawcy as "d" using(IDDostawcy)
    join kraje as "k1" on using(IDKraj)
    join klienci as "k" on using(IDKlienta)
    join kraje as "k2" on using(IDKraj)
Podobnie jak poprzednia; u Ciebie się nie da, bo klucze własne i obce noszą odmienne nazwy.

4. przez podzapytania skorelowane

Kod: Zaznacz cały

select 
    id_transakcji as "numer transakcji", 
    (select NazwaKraju from kraje where IDKraj=(select idKrajLubRegion from dostawcy as where idDostawcy = IDDostawcy)) as "kraj dostawcy", 
    (select NazwaKraju from kraje where IDKraj=(select idKrajLubRegion from klienci as where idKlienta = IDKlienta)) as "kraj kupującego"
from transakcje
Jest to najgorsza metoda, raczej nie godna polecenia.

Pisałem kod bez sprawdzania. Mogą być literówki różnego rodzaju.
JJ
LO (25.2|24.8) ∙ Python (3.12|3.10) ∙ Unicode 16 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
forami
Posty: 2
Rejestracja: pn lut 02, 2015 7:57 pm

Re: Klucz główny jako klucz obcy w dwóch tabelach

Post autor: forami »

A czy poprzez interface Base'a da się to wykonać? (Pewnie nie..)
LibreOffice Wersja: 4.2.7.2
Linux Kubuntu 14.04 LTS
Jan_J
Posty: 4626
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: Klucz główny jako klucz obcy w dwóch tabelach

Post autor: Jan_J »

Raczej tak. Base będzie wymagać pełnych kwalifikacji nazw, postaci "Tabela"."Atrybut"
JJ
LO (25.2|24.8) ∙ Python (3.12|3.10) ∙ Unicode 16 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
ODPOWIEDZ