使用MySQL从URL获取域到GROUP BY

时间:2010-01-26 20:25:11

标签: mysql

我有一张充满网址的表格。这些网址有各种格式:http://foo.comhttp://bar.foo.comhttp://foo.com/bar等。但我只对域名本身感兴趣,所以在这种情况下:foo.com。我想要做的是选择此表中存在多少次域名。如下所示:

SELECT "whatever the domain is in field 'url'", COUNT(*) AS count
FROM table_with_urls
GROUP BY "whatever the domain is in field 'url'"

Stack Overflow上有一些类似的问题,但没有真正回答这个问题。我不能使用LIKE或与REGEXP匹配,因为我不(总是)寻找特定的域名来匹配,但大多数情况下我只想从表中的所有域名以及总数。

这可以使用MySQL吗?

3 个答案:

答案 0 :(得分:9)

我有同样的问题,这就是我所做的:

select SUBSTRING(url from 1 for locate('/',url ,10)-1),count(*) from url_list group by SUBSTRING(url from 1 for locate('/',url ,10)-1);

答案 1 :(得分:5)

为“domain”添加另一个索引列,当您执行INSERT时,请单独存储此值。

答案 2 :(得分:0)

如果要安装MySQL扩展,请https://github.com/StirlingMarketingGroup/mysql-get-etld-p1

它基本上可以提取您期望的内容

select`get_etld_p1`('http://a.very.complex-domain.co.uk:8080/foo/bar');-- 'complex-domain.co.uk'
select`get_etld_p1`('https://www.bbc.co.uk/');-- 'bbc.co.uk'
select`get_etld_p1`('https://github.com/StirlingMarketingGroup/');-- 'github.com'
select`get_etld_p1`('https://localhost:10000/index');-- 'localhost'
select`get_etld_p1`('android-app://com.google.android.gm');-- 'com.google.android.gm'
select`get_etld_p1`('example.test.domain.com');-- 'domain.com'
select`get_etld_p1`('postgres://user:pass@host.com:5432/path?k=v#f');-- 'host.com'
select`get_etld_p1`('exzvk.omsk.so-ups.ru');-- 'so-ups.ru'
select`get_etld_p1`('http://10.64.3.5/data_check/index.php?r=index/rawdatacheck');-- '10.64.3.5'
select`get_etld_p1`('not a domain');-- null

然后,如果您希望它表现出色,则可以创建第二个非规范化的列,该列仅存储这些值,例如

CREATE TABLE `db`.`sometablewithurls` (
  `SomeTableWithURLsID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `URL` TEXT NOT NULL DEFAULT '',
  `_ETLDP1` VARCHAR(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`SomeTableWithURLsID`),
  INDEX `_ETLDP1` (`_ETLDP1` ASC));
DROP TRIGGER IF EXISTS `db`.`sometablewithurls_BEFORE_INSERT`;

DELIMITER $$
USE `db`$$
CREATE DEFINER = CURRENT_USER TRIGGER `db`.`sometablewithurls_BEFORE_INSERT` BEFORE INSERT ON `sometablewithurls` FOR EACH ROW
BEGIN

set new.`_ETLDP1`=ifnull(`get_etld_p1`(new.`URL`),'');

END$$
DELIMITER ;
DROP TRIGGER IF EXISTS `db`.`sometablewithurls_BEFORE_UPDATE`;

DELIMITER $$
USE `db`$$
CREATE DEFINER = CURRENT_USER TRIGGER `db`.`sometablewithurls_BEFORE_UPDATE` BEFORE UPDATE ON `sometablewithurls` FOR EACH ROW
BEGIN

set new.`_ETLDP1`=ifnull(`get_etld_p1`(new.`URL`),'');

END$$
DELIMITER ;

注意_ETLDP1上的索引(代表扩展的顶级域加1),触发器在更新时在插入时都对其进行更新,以确保其保持更新日期,即使URL更改也是如此。