Necessário para unir 2 tabelas com seus FKs em uma terceira tabela

Então, basicamente, eu estou seguindo uma pergunta tutorial que me pergunta o seguinte. Eu não estou muito certo de como juntar 2 mesas que não contenham as outras FK, suas (ie ambas as suas FKs) estão localizadas em uma terceira mesa. Eu poderia obter alguma ajuda / explicação?

Minha resposta

SELECT Forest.Fo_name, Species.Sp_name, Species.Sp_woodtype FROM Forest INNER JOIN Species ON Tree.Tr_species=Tree.Tr_forest WHERE Fo_loc='ARTIC' ORDER BY Fo_name, Sp_name 

“Para as florestas encontradas nas regiões codificadas como” ARTIC “, liste o nome da floresta e o nome da espécie e tipo de madeira da espécie encontrados. Elimine quaisquer duplicatas e ordene o resultado pelo nome da floresta e nome da espécie.

Tabela de espécies

 +--------------+------------------+------+--------------------------------+ | Field | Type | Key | Glossary | +--------------+------------------+------+--------------------------------+ | sp_name | C(10) | PK | Species Name | | sp_woodtype | C(10) | | Wood Yielded by tree | | sp_maxht | I | | Max. Height | +--------------+------------------+------+--------------------------------+ 

Mesa de floresta

 +--------------+------------------+------+--------------------------------+ | Field | Type | Key | Glossary | +--------------+------------------+------+--------------------------------+ | Fo_name | C(10) | PK | Forest Name | | Fo_size | I | | Forest Area | | Fo_loc | C(10) | | Geographical Area | | Fo_comp | C(10) | | Forest Owner | +--------------+------------------+------+--------------------------------+ 

Mesa de tree

 +--------------+------------------+------+---------------------------------------------+ | Field | Type | Key | Glossary | +--------------+------------------+------+---------------------------------------------+ | Tr_species | C(10) | FK | (FK of species.sp_name | | Tr_forest | C(10) | FK | (FK of forest.fo_name | | Tr_numb | I | PK | Sequence number | | Tr_planted | Date | | Date of planting | | Tr_loc | C(10) | | Forest quadrant | | Tr_parent | I | FK | (FK of tree.numb) procreating tree reference| +--------------+------------------+------+---------------------------------------------+ 

C (10) e I representam caractere (10) e inteiro respectivamente

Você pode fazer várias associações. Vincule a tabela de tree à sua floresta de tabelas principal e, em seguida, vincule a tabela de espécies:

 SELECT Forest.Fo_name, Species.Sp_name, Species.Sp_woodtype FROM Forest INNER JOIN Tree ON Tree.Tr_forest=Forest.Fo_name INNER JOIN Species ON Tree.Tr_species = Species.sp_name WHERE Fo_loc='ARTIC' ORDER BY Fo_name, Sp_name 

A tabela Tree é a conexão entre a tabela Floresta e a tabela Espécies. Pense nisso como dois passos:

1) A partir da tabela Forest, junte-se à tabela Tree (de Forest.Fo_name para Tree.Tr_forest )

2) Agora que a Árvore é conhecida, junte-se à tabela Species (de Tree.species para Species.sp_name )

Eu escreveria a consulta final assim:

 SELECT Forest.Fo_name, Species.Sp_name, Species.Sp_woodtype FROM Forest JOIN Tree ON Forest.Fo_name=Tree.Tr_forest JOIN Species ON Tree.species=Species.sp_name WHERE Fo_loc='ARTIC' ORDER BY Fo_name, Sp_name 

A condição ON deve comparar colunas de tabelas diferentes.

Então você acabou de juntar cada mesa passo a passo.

 SELECT DISTINCT Fo_name, Sp_name, Sp_woodtype FROM Forest AS f INNER JOIN Tree AS t ON t.Tr_forest = f.Fo_name INNER JOIN Species AS s ON t.Tr_speecies = s.Sp_name WHERE f.Fo_loc = 'ARCTIC' ORDER BY Fo_name, Sp_name 
 SELECT Forest.Fo_name, Species.Sp_name, Species.Sp_woodtype FROM Forest INNER JOIN Tree INNER JOIN Species ON Species.sp_name = Tree.Tr_species ON Forest.Fo_name=Tree.Tr_forest WHERE Fo_loc='ARTIC' ORDER BY Fo_name, Sp_name 

Experimente o método SQL 99

  SELECT DISTINCT F.Fo_name, S.Sp_name, Sp_woodtype FROM Forest F, Species S, Tree T WHERE F.Fo_name = T.Tr_Forest AND S.Sp_name = Tr_species AND f.Fo_loc = 'ARCTIC'; 

AFS são alias usados ​​para tornar o SQL mais curto e mais puro.

DISTINCT irá remover duplicados.

Chaves estrangeiras não são necessárias para unir mesas!

Então a resposta para como juntar tabelas quando nenhum FK está entre elas é apenas juntá-las .

A verdadeira questão é como escolhemos as tabelas a serem unidas (ou combinamos de qualquer outra forma).

Declarações e tabelas

Cada tabela base vem com um predicado – um modelo de instrução parametrizado pelos nomes das colunas. O valor da tabela é as linhas que fazem seu predicado em uma declaração verdadeira.

 // species [name] yields [woodtype] and has max height [maxht] Species(name,woodtype,maxht) // forest [name] has area [size] in area [loc] and owner [comp] Forest(name,size,loc,comp) // tree group [numb] is of species [species] in forest [forest] and was planted in [planted] in quadrant [loc] on date [date] with parent tree group [parent] Tree(species,forest,numb,planted,loc,parent) 

Uma consulta também possui um predicado. Seu valor também é as linhas que fazem seu predicado verdadeiro. Seu predicado é construído de acordo com suas cláusulas FROM , WHERE e outras. Um alias de tabela nomeia um valor de tabela como sua tabela base, mas com colunas prefixadas pelo alias. Portanto, seu predicado é o predicado de sua tabela base usando colunas com prefixo de alias.

 Species s 

mantém linhas satisfatórias

 species [s.name] yields [s.woodtype] and has max height [s.maxht] 

(CROSS ou INNER) JOIN coloca AND entre predicados; UNION coloca o OR entre eles; EXCETO inserções e não e ON & ONDE E em uma condição; SELECT renomeia, adiciona e descarta colunas. (Etc para outros operadores).

 Species s CROSS JOIN Forest f 

mantém filas onde

  species [s.name] yields [s.woodtype] and has max height [s.maxht] AND forest [f.name] has area [f.size] in area [f.loc] and owner [f.comp] 

(Não importa quais sejam as restrições!) Se você quisesse apenas as linhas acima com florestas nomeadas de acordo com seu tipo de madeira, você adicionaria uma condição via ... WHERE f.name=s.woodtype porque isso faz com que o valor seja linhas satisfatórias ... AND f.name=s.woodtype .

“Para as florestas encontradas nas regiões codificadas como” ARCTIC “, liste o nome da floresta e o nome da espécie e tipo de madeira da espécie encontrados. Elimine quaisquer duplicados e ordene o resultado pelo nome da floresta e nome da espécie.”

Esse é um grande predicado informal que as linhas retornadas devem satisfazer. Se tentarmos reescrevê-lo usando apenas os predicados que nos foram dados, mais AND, OR, AND NOT (etc), então podemos fazer isso apenas AND inserindo todos os três predicados (portanto, JOIN dos nomes das tabelas base) e adicionando AND Forest.loc='ARCTIC' (portanto, ON ou WHERE esta condição).

FKs (etc) e consultando (não)

PKs e FKs são casos especiais de restrições de integridade. Dados os predicados e quais situações podem surgir, apenas alguns valores do database podem surgir. Isso é o que as restrições de integridade descrevem. Eles permitem que o DBMS mantenha os valores do database que não devem surgir. (Além disso, otimize a execução de consultas). Como um nome é exclusivo em Espécies, nós o declaramos como uma chave. Idem para nome da floresta e tree numb. Porque uma espécie em Tree é um nome em Species e name é uma chave de Species que declaramos FK Tree.species-> Species.name. Idem para floresta e pai. Nada a ver com a ativação de junções. (Embora eles impliquem que um resultado de consulta também satisfaz certas restrições.)

Não importa perguntar quais são as restrições. Se houvesse valores de espécies de trees que não aparecessem como qualquer valor de nome de espécie, porque o predicado de espécies era diferente, não haveria FK Tree.species-> Species.name. Mas cada consulta continuaria retornando as linhas que satisfazem seu predicado conforme expresso em termos de predicados da tabela base . (Como o predicado da espécie seria diferente, o predicado da consulta seria diferente e suas linhas poderiam ser diferentes.)

O que determina a consulta SQL

Então a resposta para como escolhemos quais tabelas juntar (ou combinar de qualquer outra forma) é que organizamos os nomes das tabelas base, JOIN, UNION, EXCEPT e WHERE (etc) conforme apropriado para fornecer uma expressão de consulta cujos predicados são os que quero que nossas linhas sejam satisfeitas. Isso geralmente é ensinado como algo informal a ser feito pela sensação, mas agora você sabe o que liga o SQL à linguagem natural. E as restrições são irrelevantes.

Observação: o anterior pressupõe que não retornamos duplicatas de consultas. A razão pela qual não há duplicatas em tabelas no modelo relacional é para que a correspondência acima entre operadores de tabela e conectivos lógicos seja válida. No entanto, as tabelas SQL podem ter duplicatas. Onde o SQL difere do modelo relacional (em suas muitas maneiras), a consulta torna-se menos (literalmente) lógica.

Intereting Posts