8

複数の JOIN を使用してクエリを実行しているときに、テーブル名の 1 つにエイリアスを指定しないとクエリが機能しないことに気付きました。

ポイントを説明する簡単な例を次に示します。

これは機能しません:

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases on items.date=purchases.purchase_date
group by folder_id

これ

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases as p on items.date=p.purchase_date
group by folder_id

誰かがこれを説明できますか?

4

6 に答える 6

8

クエリで同じテーブル Purchases を 2 回使用しています。別の名前を付けてそれらを区別する必要があります。

エイリアスを指定する必要があります:

  • When the same table name is referenced multiple times

まったく同じ John Doe を持つ 2 人の人物を想像してみてください。ジョンに電話すると、両方があなたの電話に応答します。2 人に同じ名前を付けて、あなたが誰に電話しているかを知っていると仮定することはできません。同様に、まったく同じ名前の同じ結果セットを指定すると、SQL はどちらから値を取得するかを識別できません。SQL エンジンが混乱しないように、結果セットを区別するために別の名前を付ける必要があります。

スクリプト 1 : t1t2はエイリアス名です。

SELECT      t1.col2
FROM        table1 t1
INNER JOIN  table1 t2
ON          t1.col1 = t2.col1
  • When there is a derived table/sub query output

名前のない人に電話をかけても、あなたはその人に電話をかけることができないので、彼らはあなたに応答しません。同様に、派生テーブルの出力またはサブクエリの出力を生成する場合、それは SQL エンジンにとって未知のものであり、何を呼び出すかはわかりません。そのため、SQL エンジンがその派生出力を適切に処理できるように、派生出力に名前を付ける必要があります。

スクリプト 2 : t1はエイリアス名です。

SELECT col1
FROM
(
    SELECT col1
    FROM   table1
) t1
于 2012-05-03T14:16:37.173 に答える
5

エイリアスを指定する必要があるのは、テーブルを複数回参照するときと、出力 (テーブルとして機能するサブクエリ) を取得したときだけです (Siva を見つけてくれてありがとう)。これは、クエリの残りの部分で使用するテーブル参照の間のあいまいさを取り除くことができるようにするためです。

さらに詳しく説明するには、あなたの例では:

SELECT subject
from items
join purchases on items.folder_id=purchases.item_id
join purchases on items.date=purchases.purchase_date
group by folder_id

私の仮定では、それぞれjoinとそれに対応onするものは相関テーブルを使用すると思いますが、必要なテーブル参照を使用できます。つまり、あなたが と言うon items.date=purchases.purchase_dateと、SQL エンジンは、最初の purchases テーブルを意味するのか、2 番目のテーブルを意味するのかについて混乱します。

エイリアスを追加することで、より明確になり、あいまいさがなくなります。SQL エンジンは、使用したい購入のバージョンを 100% 確実に判断できるようになりました。2 つの等しい選択肢を推測する必要がある場合は、常にエラーをスローして、より明確にするように求めます。

于 2012-05-03T14:15:09.423 に答える
1

クエリで同じテーブルを 2 回使用する場合は、名前を付ける必要があります。あなたの場合、クエリは purchases.purchase_date から選択するテーブルを認識しません。

于 2012-05-03T14:15:13.277 に答える
1

この場合、購入を 2 回指定しただけで、SQL エンジンは結合内の各データセットを一意の方法で参照できる必要があるため、エイリアスが必要です。

余談ですが、本当に 2 回購入に参加する必要がありますか? これは機能しませんか:

SELECT 
    subject
from 
    items
    join purchases 
        on items.folder_id=purchases.item_id
        and items.date=purchases.purchase_date
group by folder_id
于 2012-05-03T14:16:17.003 に答える
1

エイリアスは、列を取得するテーブルのあいまいさを解消するために必要です。

そのため、from リスト内のテーブルで使用可能なすべての列のリスト内で列の名前が一意である場合は、その列名を直接使用できます。

from リストで使用可能ないくつかのテーブルで列の名前が繰り返される場合、DB サーバーは列を取得するのに適切なテーブルを推測する方法がありません。

サンプルクエリでは、同じテーブル (購入) の「2 つのインスタンス」を取得しているため、すべての列名が重複しているため、サーバーはどのインスタンスから列を取得するかを知る必要があります。SO を指定する必要があります。

実際、単一のテーブルがない限り、常にエイリアスを使用することをお勧めします。このようにして、多くの問題を回避し、クエリをより明確に理解できるようにします。

于 2012-05-03T14:18:35.947 に答える
0

あいまいな結合条件を防ぐために別の名前にエイリアスされていない限り、同じクエリで同じテーブル名を使用することはできません。そのため、許可されていません。また、常に修飾する table.field または alias.field を使用することをお勧めします。これにより、背後にいる他の開発者が、どの列がどのテーブルから来ているかを推測する必要がなくなります。

クエリを書くとき、あなたは自分が何を扱っているかを知っていますが、開発中のあなたの背後にいる人はどうですか. どの列がどのテーブルに由来するかについて慣れていない場合、特にここ S/O では、従うことがあいまいになる可能性があります。テーブル参照とフィールド、またはエイリアス参照とフィールドを使用して常に修飾することで、従うのがはるかに簡単になります。

select
      SomeField,
      AnotherField
   from
      OneOfMyTables
         Join SecondTable
            on SomeID = SecondID

それを比較して

select
      T1.SomeField,
      T2.AnotherField
   from
      OneOfMyTables T1
         JOIN SecondTable T2
            on T1.SomeID = T2.SecondID

これら 2 つのシナリオでは、どちらを読みたいと思いますか...注意してください。短いエイリアス "T1" と "T2" を使用してクエリを簡略化しましたが、テーブル名の頭字語や省略されたエイリアスなど、何でもかまいません.. . "oomt" (私のテーブルの 1 つ) と "st" (2 番目のテーブル)。または、他の投稿にあるように非常に長いもの...

Select * from ContractPurchaseOffice_AgencyLookupTable

vs 

Select * from ContractPurchaseOffice_AgencyLookupTable  AgencyLkup

修飾結合またはフィールド列を維持する必要がある場合は、どちらを参照することをお勧めします。

これで質問が明確になることを願っています。

于 2012-05-03T14:15:51.043 に答える