2009-08-19 4 views
2

아마도 나는 잘못된 방향으로 가고 있습니다. 여기에 내가하려고하는 것과 내 문제가있다.오른쪽 테이블을 두 번째 테이블에 두 번 조인하고 각 별칭 내부를 세 번째 테이블의 두 별칭에 연결합니다.

3 개의 테이블이 있습니다. 자산 (컴퓨터, 네트워크 장치 등) 포트 port_connections (컴퓨터, 네트워크 장치 등의 포트)

그것은 정말 (A port_id_a 및 port_id_b 필드와 링크 각 포트 및 그 함께 각 자산이있다) 오피스 빌딩의 vlans 및 네트워크 장치/컴퓨터를 추적하는 유일한 방법입니다.

저는 방언 3을 사용하는 최신 버전의 파이어 버드를 사용하고 있습니다. 파이어 버드 문제가 아니고 SQL에만 문제가 있다고 가정합니다.

올바른 조인 (port_connections 포트)을 사용하고 WHERE 절의 다른 조인을 수행 할 수 있기 때문에 이것이 가능해야한다는 것을 알고 있습니다. 문제는 자산 테이블을 포트 테이블에 조인 할 때 올바른 조인이 손실된다는 것입니다.

EDIT : 이전 쿼리가 현재 쓸모가 없기 때문에 이것은 내가 사용하고있는 가장 새로운 쿼리입니다. 이 최신 쿼리 내 문제는 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

답변

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 

편집 : 나는 내가 여기에 무슨 일이 일어나고 있는지 볼 생각합니다. 연결에서 "포트 a"로 바로 조인 할 수 있기 때문에 나중에 JOIN이 작동하는 방식으로 인해 나중에 INNER JOIN (포트 a에서 asset a로)이 일치하지 않아도 해당 행을 반환합니다. 에 연결되지 않은 행을 제외하려면, 당신은 단지 수정해야합니다 생각하여 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

이것이 효과적이었습니다 (두 개의 쉼표 제외). 내부 조인을 왼쪽 조인으로 바꿨지 만 이제는 추가 레코드를 얻을 수 있습니다. 예를 들어 나는 하나 개의 포트와 라우터의 포트 하나 port_connection으로 하나의 컴퓨터/자산이있다. 이 새로운 쿼리는 나에게 컴퓨터를 asset_a로, 라우터를 asset_b로 줄 것이다. 다음 레코드에는 asset_a null이 있고 컴퓨터는 다시 asset_b 아래에 있습니다. 이이 컴퓨터 포트 기록 만 port_connections.port_id_a 한 번 연결된 경우에도 두 번 게재 그래서 가입에 어떻게 든 가교 port_id_a 및 port_id_b을 것 같다. 당신이 왼쪽으로 당신의 일에 전체 키에 가입하지 않는 경우 – Blake

+0

당신은 여분의 기록을 얻을 것/우 조인 - 예를 들어, 키가 포트 이름과 컴퓨터 이름을 위해 구성되어, 경우,하지만 당신은 단지 컴퓨터 이름에 가입, 당신은 좋겠 포트에 대해 두 개의 레코드가 있고 어느 레코드에 합류할지 모르기 때문에 둘 다 반환합니다. 그게 무슨 일 이니? 알려면 SELECT 목록을 확장하여 컴퓨터 테이블의 일부 필드를 포함시켜 중복을 초래하는 필드를 확인해야합니다. – SqlRyan

+0

내 키는 ports 테이블의 port_id와 assets 테이블의 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

관련 문제