1

私はやろうとしています

select * 
from buildings 
where levels = 3 
join managers;

しかし、それは結合時にエラーを言います。建物の id を manager テーブルの id と一致させたいので、自然に結合したいと思います。

4

4 に答える 4

2

JOIN を適切な場所 (FROM と WHERE の間) に配置し、ON なしで JOIN を記述することが合法である場合、結果はクロス結合 (次に WHERE でフィルター処理するデカルト積) になります。

これは完全に有効なことですが、おそらくこの場合は意図したものではありません。これは、コンマ区切りのテーブルをFROM句に追加することで実現できます。たとえば、次のようになります。

FROM buildings, managers

条件に基づいて 2 つのテーブルを結合する場合は、明示的な内部結合を記述する方が一般的には優れたスタイルです。

SELECT *
FROM buildings b INNER JOIN managers m ON (b.manager_id = m.manager_id)
WHERE b.levels = 3;

ON...句が結合条件であり、bl.levels=3がフィルターであるというステートメントを読んでいる他の誰かに明らかになるからです。SQL 実装は一般に気にせず、上記を次のように変換する可能性が非常に高いです。

SELECT *
FROM buildings b, managers m
WHERE b.levels = 3 AND b.manager_id = m.manager_id;

とにかく内部的にですが、明示的な結合構文を使用して記述されている場合、多くの結合を含む複雑なクエリを理解するのは簡単です (IMO)。

あなたが望むものを書く別の方法がありますが、それは危険であり、IMO は使用すべきではありません:

SELECT * 
FROM buildings bl
NATURAL JOIN managers m                                      
WHERE bl.levels = 3;

同じ名前の列で結合します。デバッグするのは悪夢です。テーブル構造を調べて、それが何をするのかを理解する必要があります。誰かが列の名前を変更すると壊れてしまい、ただ苦痛です。使用禁止。PostgreSQL マニュアルのテーブル式を参照してください。

より受け入れられるのは、USING上記でも説明した構文です。

SELECT * 
FROM buildings bl
INNER JOIN managers m USING (manager_id)
WHERE bl.levels = 3;

manager_idcolumn と s の両方で名前が付けられた列に一致しJOIN、それらを単一の列に結合しますが、それとは異なりNATURAL JOIN、明示的に恐ろしい魔法なしでそうします。

私はまだ書くことを好みますINNER JOIN ... ON (...)が、使用するのは合理的でUSINGあり、IMO、使用するのは決して合理的ではありませんNATURAL


テスト テーブルの構造は次のとおりです。

create table managers ( manager_id integer primary key );

create table buildings (
    manager_id integer references manager(manager_id),
    levels integer
);
于 2012-09-23T23:47:11.597 に答える
1

JOINFROMテーブルに適用される演算子は、句で指定する必要があります。これを行うと、JOIN条件がないことを示す新しいエラーが発生します。これは、句のJOIN後に条件を指定する必要があるためです (オプションではありません)。ON

SELECT * 
FROM  buildings b JOIN managers m ON b.managerid = m.id
WHERE b.levels = 3 
于 2012-09-23T10:11:17.317 に答える
0

それをしたい場合は、次のように書く必要があります。

select * 
from bulidings b
join managers m on b.id=m.id
where levels = 3

リクエストは奇妙に思えますが、一方が他方への外部キーを持つべきだと思います。したがって、より適切なクエリは次のようになります。

select *
from buidings b
join managers m on b.id = m.building_id //// or b.manager_id = m.id
where levels = 3
于 2012-09-23T10:12:02.607 に答える
-1

あなたが書いたクエリは間違っていると思います。

ので、これを試してください

 select * from buildings as bl
    join managers as mn on bl.F_ManagerID = mn.ManagerID
    where bl.levels = 3

私はこれがあなたを助けると思う...

于 2012-09-23T10:14:14.130 に答える