2009-08-19 91 views
2

也許我正在以錯誤的方式去解決它。這是我想要做的和我的問題。右連接一個表兩次到第二個表,每個別名內部連接到一個第三個表的兩個別名

我有3張桌子。 資產(計算機,網絡設備等) 端口 port_connections(計算機,網絡設備等的端口)(具有port_id_a和port_id_b領域和環節的每個端口和用於其各自的資產一起)

這是真的只是一種在辦公大樓中跟蹤vlans和網絡設備/計算機的方法。

我使用最新版本的firebird使用方言3.我假設這不是一個火鳥問題,只是與我的SQL問題。

我知道這一定是可能的,因爲我可以用正確的連接(端口連接到port_connections)並在WHERE子句中執行其他連接。與此相關的問題是,當我將資產表加入端口表時,正確的連接會丟失。

編輯:這是我正在使用的最新查詢,因爲舊的在這一點上是無用的。我對這個最新的查詢的問題似乎是通過port_connections表兩次拖動鏈接的項目。所以我會得到正確的port_connections記錄,然後我得到一個沒有port_connection的單個端口的重複記錄。我需要以某種方式擺脫此後的記錄,但仍保留沒有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 

編輯:此修復程序是在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

是否可以修改您的問題以包含這三個表的模式?我試圖理解連接,沒有表格佈局就難以把它放在一起。 – SqlRyan 2009-08-19 05:37:20

回答

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 

編輯: 我想我明白是怎麼回事。由於RIGHT JOIN從Connections連接到「port a」,因爲RIGHT JOIN的行爲方式,即使稍後INNER JOIN(端口a到資產a)沒有匹配,它也會返回這些行。排除那些未插入的行,我想你只需要修改你的WHERE子句:

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

這會過濾掉行鍼對asset_a爲空,即那裏沒有匹配存在,因爲沒有被插入。

+0

這工作(減去兩個逗號)。我改變了內連接到左連接,現在它似乎關閉,但它獲得額外的記錄。 例如,我有一臺計算機/資產有一個端口和一個port_connection到路由器上的端口。這個新查詢會將計算機作爲asset_a並將路由器作爲asset_b,這是正確的。下一個記錄的asset_a爲null,計算機又在asset_b下。 看來它在某種程度上交叉連接了連接中的port_id_a和port_id_b,因此即使計算機端口記錄僅在port_connections.port_id_a上鍊接一次,它也會顯示兩次。 – Blake 2009-08-19 06:43:56

+0

如果你沒有加入你的左/右連接中的整個密鑰,你會得到額外的記錄 - 例如,如果你的密鑰是由portname和computername組成的,但你只加入computername,你會有兩個記錄的端口,它不知道哪一個加入,所以它會返回兩個。那是什麼發生?爲了說明,您可能需要展開您的SELECT列表以包含計算機表中的一些其他字段,以查看哪些字段導致重複項。 – SqlRyan 2009-08-19 17:19:08

+0

我的密鑰是端口表上的port_id,以及資產表上的asset_id。對於具有一個端口的單臺計算機,它將返回asset_a/port_a作爲計算機,asset_b/port_b作爲它插入的路由器。下一條記錄是asset_b/port_b下的計算機信息的副本,以及null的asset_a/port_a。它出現在哪裏(在a或b之下)與我的連接順序有關,但無論我嘗試什麼,我都無法擺脫這些重複項。如果我能以某種方式設置一個獨特的,所以每個端口只在port_a和port_b別名表之間列出一次。 – Blake 2009-08-19 17:50:47

相關問題