2

也许我走错了路。这是我正在尝试做的事情和我的问题。

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

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

我正在使用最新版本的火鸟,使用方言 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

端口连接

"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
4

1 回答 1

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”的 RIGHT JOIN,所以即使稍后的 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 的行,即因为没有插入任何内容而没有匹配的行。

于 2009-08-19T05:41:45.273 回答