2013-01-18 61 views
0

我有多個表中存儲數據。mysql複雜的加入與許多表可能的空值

DNS表包含

tld(id) | 2ld(id) | 3ld(id) | IPAddress 
101  | 33  | 3  | 203.11.1.19 

(實施例值)

我有dnstld表

id(index) | value(char) 
101  | 'com' 

(實施例值)

similarl y dns2ld,dns3ld。例如(33,'marriot')和dns3ld(3,'澳大利亞')包含dns2ld。

我可以加入這些表內部聯接容易

INNER JOIN dns2ld ON dns.2ld=dns2ld.id 
INNER JOIN dnstld ON dns.tld=dnstld.id 
INNER JOIN dns3ld ON dns.3ld=dns3ld.id 

但是我有另一個表包含其中包含

id(uniq) | 3ld(char) | 2ld(char) | tld(char) 

黑名單域如何加入這5個表,以便我能列出與黑名單相匹配的DNS表中的內容。黑名單3ld中的註釋可以是NULL,2ld可以是NULL,但tld不能爲空。

我可能有許多域在黑名單中,但不在dns表中,因此在dnstld,dns2ld和dns3ld表中沒有標識。

+1

使用'LEFT JOIN' – Kermit

回答

0

嚴格地說,你可能不需要Blacklist.id

假設你想列出了層次的東西(即如果未指定第二級,第三也不能被),我相信下面應該工作:

SELECT DNS.ipAddress, tld.value, 2ld.value, 3ld.value 
FROM Blacklist bl 
JOIN DNS 
    ON dns.tld = bl.tld 
    AND ((dns.2ld IS NULL AND bl.2ld IS NULL) 
      OR (dns.2ld = bl.2ld)) 
    AND ((dns.3ld IS NULL AND bl.3ld IS NULL) 
      OR (dns.2ld IS NOT NULL AND dns.3ld = bl.3ld)) 
JOIN DnsTld tld 
    ON tld.id = bl.tld 
LEFT JOIN Dns2ld 2ld 
     ON 2ld.id = bl.2ld 
LEFT JOIN Dns3ld 3ld 
     ON 3ld.id = bl.3ld 

嗯,在未來,你認爲你不能這麼用縮寫嗎?

+0

很抱歉的縮寫。 條件dns.tld = bl.tld將不起作用。由於dns.tld實際上是一個整數(這就是我指的id作爲index -sorry!),指向dnstld表中的char值。而黑名單表中實際上具有真正的字符值。 但我想我明白了。讓我嘗試一些調整並更新答案 – Vijay

0

爲了找到在DNS表中的條目列入黑名單,這個查詢應該工作:

SELECT DISTINCT dns.IPAddress, dns3ld.value, dns2ld.value, dnstld.value 
FROM dns 
INNER JOIN dnstld ON dnstld.id = dns.tld 
INNER JOIN dns2ld ON dns2ld.id = dns.2ld 
INNER JOIN dns3ld ON dns3ld.id = dns.3ld 
INNER JOIN blacklist bl 
ON bl.tld = dnstld.value 
    AND (bl.2ld IS NULL 
     OR b1.2ld = dns2ld.value 
      AND (bl.3ld IS NULL 
       OR bl.3ld = dns3ld.value)) 
+0

謝謝!這個查詢是正確的。我只是稍微調整了一下,因爲dns3ld值在數據庫中有時是空的。查詢看起來像 SELECT DISTINCT dns.IPAddress,dns3ld.value,dns2ld.value,dnstld.value 來自DNS INNER JOIN dnstld ON dnstld.id = dns.tld INNER JOIN dns2ld ON dns2ld.id = dns.2ld INNER JOIN dns3ld ON dns3ld.id = dns.3ld INNER JOIN黑名單bl ON bl。TLD = dnstld.value AND(bl.2ld IS NULL \t OR bl.2ld = dns2ld.value OR bl.2ld = '') AND(bl.3ld IS NULL OR bl.3ld = '' \t \t OR bl.3ld = dns3ld.value); – Vijay