2009-08-19 10 views
2

多分、私は間違った方法をしています。ここで私がやろうとしていることと私の問題です。2番目のテーブルに2番目のテーブルを右結合すると、各エイリアスの内側が3番目のテーブルの2つのエイリアスに結合されます

私は3つのテーブルを持っています。 資産(コンピュータ、ネットワーク機器、など) ポート port_connections(コンピュータ、ネットワーク機器などのポート)

は、それは本当にです(port_id_aとport_id_bフィールドとリンクの各ポートとその一緒にそれぞれの資産を持っています)オフィスビル内のvlansやネットワークデバイス/コンピュータを追跡するための方法です。

私はdialect 3を使ってFirebirdの最新バージョンを使用しています。これはFirebirdの問題ではなく、自分のSQLに問題があると仮定しています。

私は正しい結合(port_connectionsへのポート)でそれを行い、WHERE句で他の結合を行うことができるので、これが可能でなければならないことは知っています。この問題は、資産表をポート表に結合するときに右の結合が失われることです。

EDIT:これは私が作業している最新のクエリです。古いものはこの時点では役に立たないためです。この最新のクエリの私の問題は、port_connectionsテーブルを2度経由してリンクされているアイテムを引き出しているようです。だから、私は適切なport_connectionsレコードを取得し、次にポート接続なしで単一のポートだけを使って重複レコードを取得します。私は何とかこの後のレコードを取り除く必要がありますが、port_connectionレコードを持たない他のポートレコードを保持してください。

SELECT 
port_connections.connection_id, 

asset_a.name AS asset_a_name, 
port_a.port AS port_a_name, 
port_a.asset_id as asset_a, 

asset_b.name AS asset_b_name, 
port_b.port AS port_b_name, 
port_b.asset_id as asset_b, 

port_connections.description 

FROM 
port_connections 

right JOIN ports AS port_a 
ON port_connections.port_id_a = port_a.port_id 

right JOIN ports AS port_b 
ON port_connections.port_id_b = port_b.port_id 

left JOIN assets as asset_a 
ON asset_a.asset_id = port_a.asset_id 

left JOIN assets as asset_b 
ON asset_b.asset_id = port_b.asset_id 



WHERE 
(port_a.asset_id = 2 OR port_b.asset_id = 2) 
ORDER BY port_a_name, port_b_name 

表: 資産

ASSET_ID 
SYS_ID 
LOCATION_ID 
NAME 
DESCRIPTION 
"TYPE" 
AQUIRED 
DISPOSED 
MFG_NAME 
TAG_NO 

port_connections

"CONNECTION_ID" 
PORT_ID_A 
PORT_ID_B 
DESCRIPTION 

ポート

PORT_ID 
ASSET_ID 
PORT 
TITLE 
DESCRIPTION 
"TYPE" 
SPEED 

EDIT:修正は、ポートテーブルと番目にCONNECTION_IDを移動するましたクエリは、私が望むことをします。

SELECT 
port_connections.connection_id, 

asset_a.name AS asset_a_name, 
port_a.port AS port_a_name, 
port_a.asset_id as asset_a, 

asset_b.name AS asset_b_name, 
port_b.port AS port_b_name, 
port_b.asset_id as asset_b, 

port_connections.description 

FROM 
port_connections 



right JOIN ports AS port_b 
ON port_connections.connection_id = port_b.connection_id 

right JOIN ports AS port_a 
ON port_connections.connection_id = port_a.connection_id 

left JOIN assets as asset_a 
ON asset_a.asset_id = port_a.asset_id 

left JOIN assets as asset_b 
ON asset_b.asset_id = port_b.asset_id 

WHERE 

port_a.asset_id = 2 
AND 
(port_b.asset_id != 2 or port_b.asset_id is null) 

ORDER BY port_a_name 
+0

質問を修正して、これらの3つのテーブルのスキーマを含めることはできますか?私は結合を理解しようとしており、それをまとめるテーブルレイアウトがなければ難しいです。 – SqlRyan

答えて

1

コンパイルするようにクエリを変更し、以下に含めました。予期しないテーブル名について見ているエラーは、INNER JOIN行にあります。左のテーブル名をもう一度指定し、SQLはジョイン基準(ON句)を使用して左テーブルがあります。

これは、期待しているすべての行を返しますか、そうでない結果が表示されると思われますか?

SELECT 
port_connections.connection_id, 

asset_a.name AS asset_a_name, 
port_a.port AS port_a_name, 
port_a.asset_id as asset_a, 

asset_b.name AS asset_b_name, 
port_b.port AS port_b_name, 
port_b.asset_id as asset_b, 

port_connections.description 

FROM 
port_connections 
RIGHT JOIN ports AS port_a 
ON port_connections.port_id_a = port_a.port_id 

RIGHT JOIN ports AS port_b 
ON port_connections.port_id_b = port_b.port_id 

INNER JOIN assets as asset_a 
ON asset_a.asset_id = port_a.asset_id 

INNER JOIN assets as asset_b 
ON asset_b.asset_id = port_b.asset_id 

WHERE 
(asset_a.asset_id = 2 OR asset_b.asset_id = 2) 

ORDER BY port_a_name, port_b_name 

EDIT: 私はここで何が起こっているか見ると思います。接続から「ポートa」へ右ジョインするので、後でINNER JOIN(ポートaとアセットa)が一致しない場合でも、RIGHT JOINの動作のためにこれらの行が返されます。中に差し込まれていない行を除外するために、私はあなただけ変更する必要があると思うあなたのWHERE句:これは、行を除外します

WHERE 
(asset_a.asset_id = 2 OR asset_b.asset_id = 2) 
    AND asset_a.asset_id IS NOT NULL 

asset_aがNULLであるため、つまり何もするのでそこには、一致がありませんプラグが差し込まれています。

+0

これは機能しました(2つのカンマを差し引いたもの)。内部結合を左結合に変更しましたが、今はそれが余分な記録を得ています。 たとえば、1つのポートと1つのポート接続を持つ1つのコンピュータ/アセットがルータのポートにあります。この新しいクエリは私にコンピュータをasset_aとして与え、ルータをasset_bとして与えます。これは正しいです。次のレコードにはasset_a nullがあり、コンピュータは再びasset_bの下にあります。 コンピュータのポートレコードがport_connections.port_id_aに一度だけリンクされていても、それは何とかport_id_aとjoin_port_id_bをクロスリンクしているようです。 – Blake

+0

左/右のジョインのいずれかでキー全体に参加していない場合は、余分なレコードが得られます。たとえば、ポート名とコンピュータ名のキーが作成されていて、ポートの2つのレコードを持っていて、どのレコードに加入するのか分からないので、両方を返します。それは何が起こっているのですか?伝えるには、コンピュータテーブルのいくつかの追加フィールドを含むようにSELECTリストを拡張して、どのフィールドが重複を引き起こしているかを確認する必要があります。 – SqlRyan

+0

私のキーはportsテーブルのport_idとassetsテーブルのasset_idです。 1つのポートを持つ単一のコンピュータでは、コンピュータとしてasset_a/port_a、接続先のルータとしてasset_b/port_bを返します。次のレコードは、asset_b/port_bおよびnull asset_a/port_aの下にあるコンピュータ情報の複製です。それが表示される場所(aまたはbの下)は、私の結合の順序と関係がありますが、何を試しても、これらの重複を取り除くことはできません。私は何とか別のポートを設定することができれば、すべてのポートはport_aとport_bエイリアステーブルの間に1回だけリストされます。 – Blake

関連する問題