Mysql查询从dns域名中提取tld

时间:2015-05-24 05:47:35

标签: mysql dns

在这种做法中,我想根据下表从TLD(顶级域名)中取出域名。

Table name: dns
+---------------------------+
| dnsdomain                 |
+---------------------------+
| ns2.hosting.indo.net.id.  |
| ns1.onepanel.indo.net.id. |
| ns-1591.awsdns-06.co.uk.  |
| mail189.atl21.rsgsv.net.  |
| gli.websitewelcome.com.   |
| ns2.metrolink.pl.         |
| ns1.metrolink.pl.         |
| ns-1591.awsdns-06.co.uk.  |
| NS3.METRORED.HN.          |
| NS.METRORED.HN.           |
| ns2.hosting.indo.net.id.  |
| ns1.onepanel.indo.net.id. |
| www.csis.ul.ie.           |
+---------------------------+
and 
Table name: tld
+----------+
| tld      |
+----------+
| .net.id. |
| .co.uk.  |
| .net.    |
| .com.    |
| .pl.     |
| .uk.     |
| .hn.     |
| .id.     |
| .ie.     |
+----------+

我想用相关的tld打印出dnstomain。我执行以下mysql查询:

select test.dnsdomain , tld.tld from test join tld where locate(tld.tld, test.dnsdomain, length(test.dnsdomain) - length (tld.tld) )!= 0; 

并获得下表:

+---------------------------+----------+
| dnsdomain                 | tld      |
+---------------------------+----------+
| ns2.hosting.indo.net.id.  | .net.id. |
| ns1.onepanel.indo.net.id. | .net.id. |
| ns-1591.awsdns-06.co.uk.  | .co.uk.  |
| mail189.atl21.rsgsv.net.  | .net.    |
| gli.websitewelcome.com.   | .com.    |
| ns2.metrolink.pl.         | .pl.     |
| ns1.metrolink.pl.         | .pl.     |
| ns-1591.awsdns-06.co.uk.  | .uk.     |
| NS3.METRORED.HN.          | .hn.     |
| NS.METRORED.HN.           | .hn.     |
| ns2.hosting.indo.net.id.  | .id.     |
| ns1.onepanel.indo.net.id. | .id.     |
| www.csis.ul.ie.           | .ie.     |
+---------------------------+----------+

我的查询的问题是,对于表'test'中的每一条记录,它都没有检查表'tld'中的所有tld,这就是我看到类似内容的原因:

| ns-1591.awsdns-06.co.uk.  | .uk.     |

预期结果如下:

| ns-1591.awsdns-06.co.uk.  | .co.uk.  |

我做错了什么?

2 个答案:

答案 0 :(得分:1)

你没有做错任何事。该dnsname 'blah.co.uk.''.co.uk.''.uk.'都匹配。两行都被返回。

听起来你想过滤除“最长”匹配tld之外的所有匹配。

注意:我更倾向于使用RIGHT()函数从dnsdomain中提取最右边的部分。 (这对我来说更容易理解,但它应该等同于你正在使用的表达式。)

参考:RIGHT() https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_right

过滤掉较短匹配的一个选项是使用相关子查询来确定匹配的所有tld最大长度,并仅返回tld那个长度。

例如:

SELECT test.dnsdomain
     , tld.tld
  FROM test
  JOIN tld 
    ON tld.tld = RIGHT(test.tndsdomain,CHAR_LENGTH(tld.tld))
 WHERE CHAR_LENGTH(tld.tld) = 
       ( SELECT MAX(CHAR_LENGTH(m.tld))
           FROM tld m
          WHERE m.tld = RIGHT(test.tndsdomain,CHAR_LENGTH(m.tld))
       )

您可以使用JOIN操作获得与内联视图相同的结果,它基本上做同样的事情:

SELECT test.dnsdomain
     , tld.tld
  FROM test
  JOIN tld 
    ON tld.tld = RIGHT(test.tndsdomain,CHAR_LENGTH(tld.tld))
  JOIN ( SELECT n.dnsdomain
              , MAX(CHAR_LENGTH(m.tld)) AS tld_len 
           FROM test n
           JOIN tld m 
             ON m.tld = RIGHT(n.tndsdomain,CHAR_LENGTH(m.tld))
          GROUP BY n.dnsdomain
       ) o
    ON o.dnsdomain = test.dnsdomain
   AND o.tld_len = CHAR_LENGTH(tld.tld)

此外,最好使用 CHAR_LENGTH() 功能而不是 LENGTH() 功能。对于单字节字符集(如LENGTH()),latin1函数返回一些字节数,与字符数相同,但对于多字节字符集,字符数可能小于字节数。)

答案 1 :(得分:1)

尝试使用Group By功能。此语句适用于 mysql

select test.dnsdomain , tld.tld ,
max(length(tld.tld)) as x
from test 
join tld 
where locate(tld.tld, test.dnsdomain, length(test.dnsdomain) - length (tld.tld) )!= 0; 
group by test.tnsdomain

OR

 select test.dnsdomain , max(tld.tld) as tld
    from test 
    join tld 
    where locate(tld.tld, test.dnsdomain, length(test.dnsdomain) - length (tld.tld) )!= 0; 
    group by test.tnsdomain
相关问题