如果在错误的四分位数中,您可以使用IF将它们设置为零来创建四分位数值:

我们假设,原始数据表是由

DROP TABLE IF EXISTS `rawdata`;

CREATE TABLE `rawdata` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`url` varchar(250) NOT NULL DEFAULT '',

`time` int(11) NOT NULL,

PRIMARY KEY (`id`),

KEY `time` (`time`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;(当然是人口稠密的)。

我们还假设由四分位表数据创建

DROP TABLE IF EXISTS `quartiles`;

CREATE TABLE `quartiles` (

`url` varchar(250) NOT NULL,

`Q1` float DEFAULT '0',

`Q2` float DEFAULT '0',

`Q3` float DEFAULT '0',

`Q4` float DEFAULT '0',

PRIMARY KEY (`url`),

) ENGINE=MyISAM DEFAULT CHARSET=utf8;(并留空)。

然后从rawdata填充四分位的过程看起来像

DELIMITER ;;

CREATE PROCEDURE `ComputeQuartiles`()

READS SQL DATA

BEGIN

DECLARE numrows int DEFAULT 0;

DECLARE qrows int DEFAULT 0;

DECLARE rownum int DEFAULT 0;

DECLARE done int DEFAULT 0;

DECLARE currenturl VARCHAR(250) CHARACTER SET utf8;

DECLARE Q1,Q2,Q3,Q4 float DEFAULT 0.0;

DECLARE allurls CURSOR FOR SELECT DISTINCT url FROM rawdata;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET currenturl='';

OPEN allurls;

FETCH allurls INTO currenturl;

WHILE currenturl<>'' DO

SELECT COUNT(*) INTO numrows FROM rawdata WHERE url=currenturl;

SET qrows=FLOOR(numrows/4);

if qrows>0 THEN

-- Only session parameters can be recalculated inside a query,

-- so @rownum:=@rownum+1 will work, but rownum:=rownum+1 will not.

SET @rownum=0;

SELECT

SUM(IFNULL(QA,0))/qrows,

SUM(IFNULL(QB,0))/qrows,

SUM(IFNULL(QC,0))/qrows,

SUM(IFNULL(QD,0))/qrows

FROM (

SELECT

if(@rownum

if(@rownum>=qrows AND @rownum<2*qrows,time,0) AS QB,

-- the middle 0-3 rows are left out

if(@rownum>=(numrows-2*qrows) AND @rownum

if(@rownum>=(numrows-qrows),time,0) AS QD,

@rownum:=@rownum+1 AS dummy

FROM rawdata

WHERE url=currenturl ORDER BY time

) AS baseview

INTO Q1,Q2,Q3,Q4

;

REPLACE INTO quartiles values (currenturl,Q1,Q2,Q3,Q4);

END IF;

FETCH allurls INTO currenturl;

END WHILE;

CLOSE allurls;

END ;;

DELIMITER ;要点是:

使用游标循环URL(或调整样本以接受URL作为参数)

对于每个网址,找到总行数

如果(rowcount % 4) != 0,请做一些简单的数学运算来省略中间行

选择URL的所有原始行,将time的值分配给QA-QD之一,具体取决于行号,为其他Qx分配值0

将此查询用作另一个查询的子查询,该查询汇总并规范化值

使用此超级查询的结果更新四分位表

我在8x1.9GHz机器上用18432个原始行url=concat('http://.../',floor(rand()*10)), time=round(rand()*10000)进行了测试,并在0.50-0.54秒内始终如一地完成测试

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐