Mysql 从 dns 域名中提取 tld 的查询
Mysql query to extract tld from dns domain names
在这个练习中,我想从 TLD(顶级域)中提取域名,给出以下 tables。
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. |
+----------+
我想打印出 dnstomain 及其相关的顶级域名。我执行以下 mysql 查询:
select test.dnsdomain , tld.tld from test join tld where locate(tld.tld, test.dnsdomain, length(test.dnsdomain) - length (tld.tld) )!= 0;
并得到以下 table:
+---------------------------+----------+
| 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. |
+---------------------------+----------+
我的查询的问题是,对于 table 'test' 中的每条记录,它不会检查 table 'tld' 中的所有顶级域名,这就是我看到一些东西的原因喜欢:
| ns-1591.awsdns-06.co.uk. | .uk. |
预期结果如下:
| ns-1591.awsdns-06.co.uk. | .co.uk. |
我做错了什么?
你没有做错任何事。 dnsname 'blah.co.uk.'
匹配 '.co.uk.'
和 '.uk.'
。两行都在 returned.
听起来您想过滤掉除了 "longest" 匹配 tld
.
之外的所有内容
注意:我更喜欢使用 RIGHT()
函数从 dnsdomain
中提取最右边的部分。 (这对我来说更容易理解,但它应该等同于您使用的表达式。)
参考:RIGHT()
https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_right
过滤掉较短匹配的一个选项是使用相关子查询来确定所有匹配的 tld
的 最大 长度,并且只有 return 具有该长度的 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()
函数 returns 字节数,对于单字节字符集(如 latin1
),与字符数相同,但对于多字节字符集,字符数可以小于字节数。)
试试 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
在这个练习中,我想从 TLD(顶级域)中提取域名,给出以下 tables。
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. |
+----------+
我想打印出 dnstomain 及其相关的顶级域名。我执行以下 mysql 查询:
select test.dnsdomain , tld.tld from test join tld where locate(tld.tld, test.dnsdomain, length(test.dnsdomain) - length (tld.tld) )!= 0;
并得到以下 table:
+---------------------------+----------+
| 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. |
+---------------------------+----------+
我的查询的问题是,对于 table 'test' 中的每条记录,它不会检查 table 'tld' 中的所有顶级域名,这就是我看到一些东西的原因喜欢:
| ns-1591.awsdns-06.co.uk. | .uk. |
预期结果如下:
| ns-1591.awsdns-06.co.uk. | .co.uk. |
我做错了什么?
你没有做错任何事。 dnsname 'blah.co.uk.'
匹配 '.co.uk.'
和 '.uk.'
。两行都在 returned.
听起来您想过滤掉除了 "longest" 匹配 tld
.
注意:我更喜欢使用 RIGHT()
函数从 dnsdomain
中提取最右边的部分。 (这对我来说更容易理解,但它应该等同于您使用的表达式。)
参考:RIGHT()
https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_right
过滤掉较短匹配的一个选项是使用相关子查询来确定所有匹配的 tld
的 最大 长度,并且只有 return 具有该长度的 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()
函数 returns 字节数,对于单字节字符集(如 latin1
),与字符数相同,但对于多字节字符集,字符数可以小于字节数。)
试试 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