2016-09-22 7 views
1

データをフィルタリングするのにtNetworkSockettPatchpanelPortsの2つのテーブルがあります。
SELECT * FROM tPatchpanelPortsを実行するとデータがありますが、SELECT * FROM tNetworkSocketにはデータがありません。これは正しいです。
私はテーブルの1つにデータがあってもSQL - クエリの結合結果が空です

SELECT Distinct HostID, HostName, HostTypeID, DomainName 
FROM tHosts, tDomains, tPatchpanelPorts, tNetworkSocketPort 
WHERE tHosts.DomainID=tDomains.DomainID 
AND (tPatchpanelPorts.ConnectedHostID = tHosts.HostID OR tNetworkSocketPort.ConnectedHostID = tHosts.HostID) And AccountID=1 

を実行した場合、私は何のデータを取得していないが、私は、クエリからtNetworkSocketPortを削除する場合のように見える:私はデータを取得

SELECT Distinct HostID, HostName, HostTypeID, DomainName 
FROM tHosts, tDomains, tPatchpanelPorts 
WHERE tHosts.DomainID=tDomains.DomainID 
AND (tPatchpanelPorts.ConnectedHostID = tHosts.HostID) And AccountID=1 

は私が明示的で

+2

あなたは 'INNER JOINをない場合'データなしのテーブルには、すべての結果を効果的にフィルタリングします。 – Siyual

+6

最新の明示的なJOIN構文に切り替えます。 (エラーなし)、読みやすく、外部結合(必要な場合)に変換する方が簡単です。 – jarlh

+5

ところで、あなたはMySQLまたはMS SQL Serverを使用していますか? (含まれていない製品にタグを付けないでください) – jarlh

答えて

1

書き換えクエリ行方不明だJOIN構文を、テーブルのために、私はこれがあなたに

SELECT Distinct HostID, HostName, HostTypeID, DomainName 
FROM tHosts 
INNER JOIN tDomains ON tHosts.DomainID=tDomains.DomainID 
INNER JOIN tPatchpanelPorts ON tPatchpanelPorts.ConnectedHostID = tHosts.HostID 
LEFT JOIN tNetworkSocketPort ON tNetworkSocketPort.ConnectedHostID = tHosts.HostID 
WHERE AccountID=1 
+0

最初のクエリでは、この1つまたはtNetworkSocketPortがHostIDと一致する必要があるため、私はtPatchpanelPortsをLEFT JOINとして持っています。したがって、tNetworkSocketPortで行っても、一致するHostIDを持たないレコードをtPatchpanelPortsで除外します。 OPが明確になる可能性があります – kbball

+0

tNetworkSocketPortの結合を削除することは、クエリに影響を与えないためです。 tPatchpanelPortsの内部結合を使用してから 'DISTINCT'を適用するのは、' IN'または 'EXISTS'節をエミュレートする不器用な方法ですが、外部結合と同じことは単に何もしません(DBMSに不要な作業をさせることを除く) 。この答えが受け入れられたにもかかわらず、元のクエリに含まれているtNetworkSocketPortのために、クエリがOPの処理を望んでいるとは限りませんが、実際にはこのクエリには含まれていません。 –

+0

@ThorstenKettnerまあ、このような素敵な説明をありがとう、私はあなたの努力に感謝しますが、OPが彼が探しているものを持っている可能性があります。 –

1

を助けるかもしれない、LEFT JOINは使用していたいくつかと、このようにそれを試してみてくださいジョイン:

SELECT Distinct HostID, HostName, HostTypeID, DomainName 
FROM tHosts 
INNER JOIN tDomains 
ON tHosts.DomainID=tDomains.DomainID 
LEFT JOIN tPatchpanelPorts 
ON tPatchpanelPorts.ConnectedHostID = tHosts.HostID 
LEFT JOIN tNetworkSocketPort 
ON tNetworkSocketPort.ConnectedHostID = tHosts.HostID 
WHERE AccountID=1 
1

使用している古い日付のカンマ区切りの結合は、読みにくいです。あなたはすべての可能な組み合わせを得るためにtPatchpanelPortsとtNetworkSocketPortに参加交差

SELECT Distinct HostID, HostName, HostTypeID, DomainName 
FROM tPatchpanelPorts pp 
CROSS JOIN tNetworkSocketPort nsp 
JOIN tHosts h ON h.HostID IN (pp.ConnectedHostID, nsp.ConnectedHostID) 
JOIN tDomains d on d.DomainID = h.DomainID 
WHERE AccountID = 1; 

:あなたのクエリがに変換されます。テーブルの1つが空であるため、可能な組合せはゼロです。次に、空のままのこの空の結果セットに他のテーブルを結合します。

さらに、DISTINCTは、よく記述されていないクエリの兆候です。そして、実際には、2つのテーブルのデータだけが必要なときに、4つのテーブルに参加しています。他のテーブルはWHERE節に属します。

私はあなたがこれをしたいと仮定します。

SELECT h.HostID, h.HostName, h.HostTypeID, d.DomainName 
FROM tHosts h 
JOIN tDomains d ON d.DomainID = h.DomainID 
WHERE AccountID = 1 
AND 
( 
    h.HostID IN (SELECT ConnectedHostID FROM tPatchpanelPorts) 
    OR 
    h.HostID IN (SELECT ConnectedHostID FROM tNetworkSocketPort) 
); 

(私はアカウントIDがtHostsかTDOMAINSのいずれかに存在すると仮定しますが、これは明確にするために修飾子を使用する必要があります。。)

関連する問題