mysql复杂连接与许多具有可能空值的表

时间:2013-01-18 23:09:23

标签: mysql sql

我有多个表存储数据。

DNS表格包含

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

(示例值)

我有 dnstld表

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

(示例值)

同样 dns2ld,dns3ld

dns2ld包含,例如(33,'marriot')和dns3ld有(3,'australia')。

我可以轻松加入这些表与内联接

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表中没有标识。

2 个答案:

答案 0 :(得分: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
嗯,将来你认为你不能使用缩写吗?

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