右键将表连接两次到第二个表,每个别名内部连接到第三个表的两个别名

时间:2009-08-19 04:06:09

标签: join inner-join alias firebird

也许我会以错误的方式去做。这是我正在尝试做的和我的问题。

我有3张桌子。 资产(计算机,网络设备等) 端口(计算机上的端口,网络设备等) port_connections(有一个port_id_a和port_id_b字段,并将每个端口和每个资产链接在一起)

这实际上只是一种跟踪办公楼中的vlans和网络设备/计算机的方法。

我正在使用最新版本的firebird使用方言3.我假设这不是火鸟问题而只是我的sql问题。

我知道这一定是可能的,因为我可以通过正确的连接(端口到port_connections)来完成它,并在WHERE子句中执行其他连接。这个问题是当我将资产表加入ports表时,正确的连接会丢失。

编辑:这是我正在使用的最新查询,因为旧的查询在这一点上毫无用处。我对这个最新查询的问题是它似乎拉动了通过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移动到ports表中,然后此查询执行我想要的操作。

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

1 个答案:

答案 0 :(得分: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

修改 我想我看到这里发生了什么。因为您正在从Connections连接到“端口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的行,即那里没有匹配的行,因为没有插入任何内容。