在这种做法中,我想根据下表从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. |
我做错了什么?
答案 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