【问题标题】:Mysql query to extract tld from dns domain namesMysql查询从dns域名中提取tld
【发布时间】:2015-08-05 21:09:03
【问题描述】:

在此实践中,我想从给定下表的 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.  |

我做错了什么?

【问题讨论】:

  • 只是快速编辑。第一个表的正确名称是“测试”。我错误地输入了“dns”。

标签: mysql dns


【解决方案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),但对于多字节字符集,字符数可以小于字节数.)

【讨论】:

  • 我对第一个查询进行了一些更改(更正了一些拼写错误): SELECT test.dnsdomain , tld.tld FROM test JOIN tld ON tld.tld = RIGHT(test.dnsdomain,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.dnsdomain,CHAR_LENGTH(m.tld)) GROUP BY n .dnsdomain ) o ON o.dnsdomain = test.dnsdomain AND o.tld_len = CHAR_LENGTH(tld.tld);
【解决方案2】:

试试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

 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

【讨论】:

  • 好主意 :) 非常感谢
猜你喜欢
  • 1970-01-01
  • 2010-11-07
  • 2010-10-16
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多