2

基本的に、私は以下を尋ねるチュートリアルの質問に従っています。他の FK を含まない 2 つのテーブルを結合する方法がよくわかりません。それら (つまり、両方の FK) は 3 番目のテーブルにあります。ヘルプ/説明をもらえますか?

私の答え

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

「「ARTIC」としてコード化された地域で見つかった森林については、そこで見つかった森林の名前と種の名前、および種の木材の種類をリストします。重複を排除し、出力を森林の名前と種の名前で並べ替えます」

種表

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

森のテーブル

+--------------+------------------+------+--------------------------------+
| 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                   |
+--------------+------------------+------+--------------------------------+

木のテーブル

+--------------+------------------+------+---------------------------------------------+
| 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) & I はそれぞれ文字 (10) & 整数を表します

4

6 に答える 6

3

テーブルを結合するのに外部キーは必要ありません!

したがって、テーブル間に FK がないときにテーブルを結合する方法の答えは、単に結合することです。

本当の問題は、どのテーブルをどのように結合 (または他の方法で結合) するかということです。

ステートメントと表

すべてのベース テーブルには、列名でパラメーター化された述語--statement テンプレートが付属しています。テーブルの値は、その述語を真の命題--statement にする行です。

// 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)

クエリには述語もあります。その値は、その述語を真にする行でもあります。その述語はFROMWHEREおよびその他の節に従って構築されます。テーブル エイリアスは、ベース テーブルと同様にテーブル値に名前を付けますが、列にはエイリアスのプレフィックスが付きます。したがって、その述語は、エイリアスがプレフィックスされた列を使用するベース テーブルの述語です。

Species s

満足する行を保持します

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

CROSS & INNER JOIN put AND 述語の間に; UNION はそれらの間に OR を置きます。EXCEPT は AND NOT および ON & WHERE AND を条件に挿入します。SELECT は、列の名前変更、追加、削除を行います。(他の事業者の場合など)

Species s CROSS JOIN Forest f

行を保持します

    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]

(制約が何であれ!) 木の種類にちなんで名前が付けられた森林を持つ上記の行のみが必要な場合は、条件を追加するだけ... WHERE f.name=s.woodtypeです... AND f.name=s.woodtype

「北極」とコード化された地域で見つかった森林については、そこに見られる森林の名前と種の名前、および種の木材の種類をリストします。重複を排除し、出力を森林名と種名で並べ替えます。

これは、返される行が満たす大きな非公式の述語です。与えられた述語と AND、OR、AND NOT (など) のみを使用して書き直そうとすると、AND与えられた 3 つの述語 (したがって、JOINベース テーブル名) をすべて ing し、追加するAND Forest.loc='ARCTIC'(したがって、 、ONまたはWHEREその状態)。

FK (etc) とクエリ (not)

PK と FK は、整合性制約の特殊なケースです。述部と発生する可能性のある状況を考えると、一部のデータベース値のみが発生する可能性があります。それが整合性制約の説明です。これにより、発生してはならないデータベース値を DBMS が除外できるようになります。(また、クエリの実行を最適化します。) 名前は Species 内で一意であるため、キーとして宣言します。Forest name と Tree numb についても同様です。Tree の種は Species の名前であり、name は Species のキーであるため、FK Tree.species->Species.name を宣言します。フォレストと親についても同様です。結合を有効にすることとは関係ありません。(ただし、クエリ結果が特定の制約も満たしていることを暗示しています。)

制約が何であるかを照会することは重要ではありません。ビジネス ルールまたは Tree または Species の述語が異なるために、どの Species 名の値としても表示されない Tree 種の値がある場合、FK Tree.species->Species.name はありません。ただし、各クエリは、ベース テーブルの述語で表された述語を満たす行を引き続き返します。(考えられるビジネス状況または述語が異なるため、入力行が異なる可能性があり、出力行が異なる可能性があります。)

クエリ SQL を決定するもの

したがって、結合する (または他の方法で結合する) テーブルを選択する方法に対する答えは、ベース テーブル名、JOIN、UNION、EXCEPT、および WHERE (など) を適切に配置して、述語がその述語であるクエリ式を与えることです。私たちの行が満たされることを望みます。これは通常、非公式に感じて行うものとして教えられますが、SQL と自然言語を結びつけるものは何なのかがわかりました。そして、制約は無関係です。

注: 上記は、クエリから重複を返さないことを前提としています。リレーショナルモデルで表に重複がないのは、上記の表演算子と論理接続詞の対応関係が成立するためです。ただし、SQL テーブルは重複する可能性があります。SQL が (多くの点で) リレーショナル モデルと異なる場合、クエリは (文字通り) 論理的ではなくなります。

外部キーに続く再結合
テーブルの選択再
人間が読める記述から SQL クエリを構築するための経験則はありますか?

于 2014-05-24T06:40:19.397 に答える
3

このTreeテーブルは、Forest テーブルと Species テーブルの間の接続です。次の 2 つのステップと考えてください。

1) フォレスト テーブルから始めて、テーブルに参加しTreeます (からForest.Fo_nameまでTree.Tr_forest)

2) ツリーがわかったので、Speciesテーブルに参加します (からTree.speciesまでSpecies.sp_name)

最終的なクエリは次のように書きます。

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
于 2014-05-23T23:05:21.680 に答える
1

複数の結合を行うことができます。ツリー テーブルをメイン テーブルのフォレストにリンクしてから、種のテーブルをリンクします。

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
于 2014-05-23T23:05:01.480 に答える
0

ON条件は、異なるテーブルの列を比較する必要があります。

次に、各テーブルを段階的に結合します。

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
于 2014-05-23T23:05:17.973 に答える
0
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
于 2014-05-23T23:07:00.110 に答える