在这里,我提出了一种从日志表中按天和平台检索 MAU 的方法。
这是通过在过程中使用临时表来完成的。
任何人都知道查询这个的最快方法吗?
/* CREATE LOG TABLE EXAMPLE */
CREATE TABLE TEST_LOG (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT
, DTIME DATETIME
, USERID BIGINT UNSIGNED NOT NULL
, PLATFORM CHAR(25) NULL
, PRIMARY KEY (ID)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/* CREATE PROCEDURE TO ADD SOME TEST DATA INTO TEST_LOG */
DROP PROCEDURE IF EXISTS ADD_TEST_DATA;
DELIMITER |
CREATE PROCEDURE ADD_TEST_DATA(DATE_START DATETIME, DATE_END DATETIME)
BEGIN
DECLARE T_PRAND INTEGER DEFAULT NULL;
DECLARE T_COUNT INTEGER DEFAULT NULL;
DECLARE T_URAND INTEGER DEFAULT NULL;
DECLARE T_PLATF INTEGER DEFAULT NULL;
DECLARE T_PLATN CHAR(25) DEFAULT NULL;
WHILE DATE_START <= DATE_END DO
SELECT FLOOR(1+RAND()*10) INTO T_PRAND FROM DUAL; /* 1-10 RANDOM LOGS FOR EACH DAY */
SET T_COUNT = 0;
WHILE T_COUNT <= T_PRAND DO
SELECT FLOOR(1+RAND()*1000) INTO T_URAND FROM DUAL; /* RANDOM USER */
SELECT FLOOR(1+RAND()*5) INTO T_PLATF FROM DUAL; /* RANDOM PLATFORM */
CASE T_PLATF
WHEN 1 THEN SET T_PLATN = 'WEB';
WHEN 2 THEN SET T_PLATN = 'FACEBOOK';
WHEN 3 THEN SET T_PLATN = 'IPHONE';
WHEN 4 THEN SET T_PLATN = 'IPAD';
WHEN 5 THEN SET T_PLATN = 'ANDROID';
ELSE
BEGIN
END;
END CASE;
INSERT INTO TEST_LOG (DTIME,USERID,PLATFORM) VALUES (DATE_START, T_URAND, T_PLATN);
SET T_COUNT = T_COUNT+1;
END WHILE;
SET DATE_START = DATE_ADD(DATE_START, INTERVAL 1 DAY);
END WHILE;
END
|
;
CALL ADD_TEST_DATA('2013-01-01 00:00:00', '2013-03-25 23:59:59'); /* SAMPLE DATE CREATION */
/* CREATE PROCEDURE TO CALCULATE MAU */
DROP PROCEDURE IF EXISTS MAU;
DELIMITER |
CREATE PROCEDURE MAU(DATE_START DATETIME, DATE_END DATETIME)
BEGIN
DECLARE T_DTIME DATETIME DEFAULT NULL;
DECLARE T_ATOTAL INTEGER DEFAULT NULL;
DECLARE T_WEB CHAR(10) DEFAULT NULL;
DECLARE T_FACEBOOK CHAR(10) DEFAULT NULL;
DECLARE T_IPHONE CHAR(10) DEFAULT NULL;
DECLARE T_IPAD CHAR(10) DEFAULT NULL;
DECLARE T_ANDROID CHAR(10) DEFAULT NULL;
DECLARE T_UNKNOWN CHAR(10) DEFAULT NULL;
DROP TEMPORARY TABLE IF EXISTS TEMP_RESULTS;
CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_RESULTS (
TEMP_DTIME DATE,
TEMP_ATOTAL INTEGER,
TEMP_WEB CHAR(10) DEFAULT NULL,
TEMP_FACEBOOK CHAR(10) DEFAULT NULL,
TEMP_IPHONE CHAR(10) DEFAULT NULL,
TEMP_IPAD CHAR(10) DEFAULT NULL,
TEMP_ANDROID CHAR(10) DEFAULT NULL,
TEMP_UNKNOWN CHAR(10) DEFAULT NULL
);
WHILE DATE_START <= DATE_END DO
SELECT DATE(DATE_START),
COUNT( DISTINCT USERID ) AS UNIQUE_TOTAL,
COUNT( DISTINCT CASE WHEN PLATFORM='WEB' THEN USERID ELSE NULL END ) AS WEB,
COUNT( DISTINCT CASE WHEN PLATFORM='FACEBOOK' THEN USERID ELSE NULL END ) AS FACEBOOK,
COUNT( DISTINCT CASE WHEN PLATFORM='IPHONE' THEN USERID ELSE NULL END ) AS IPHONE,
COUNT( DISTINCT CASE WHEN PLATFORM='IPAD' THEN USERID ELSE NULL END ) AS IPAD,
COUNT( DISTINCT CASE WHEN PLATFORM='ANDROID' THEN USERID ELSE NULL END ) AS ANDROID,
COUNT( DISTINCT CASE WHEN PLATFORM <> 'WEB'
AND PLATFORM <> 'FACEBOOK'
AND PLATFORM <> 'IPHONE'
AND PLATFORM <> 'IPAD'
AND PLATFORM <> 'ANDROID'
THEN USERID ELSE NULL END ) AS UNKNOWN
INTO T_DTIME, T_ATOTAL, T_WEB, T_FACEBOOK, T_IPHONE, T_IPAD, T_ANDROID, T_UNKNOWN
FROM TEST_LOG
WHERE ID >= 1
AND DTIME > DATE_START + INTERVAL -1 MONTH
AND DTIME <= DATE_START;
INSERT INTO TEMP_RESULTS VALUES (T_DTIME, T_ATOTAL, T_WEB, T_FACEBOOK, T_IPHONE, T_IPAD, T_ANDROID, T_UNKNOWN);
SET DATE_START = DATE_START + INTERVAL 1 DAY;
END WHILE;
SELECT TEMP_DTIME AS DATE, TEMP_ATOTAL AS TOTAL_UNIQUE, TEMP_WEB AS WEB, TEMP_FACEBOOK AS FACEBOOK,
TEMP_IPHONE AS IPHONE, TEMP_IPAD AS IPAD, TEMP_ANDROID AS ANDROID, TEMP_UNKNOWN AS UNKNOWN
FROM TEMP_RESULTS;
DROP TEMPORARY TABLE IF EXISTS TEMP_RESULTS;
END
|
;
CALL MAU('2013-01-01 00:00:00', '2013-03-25 23:59:59'); /* QUERYING SAMPLE DATA */
任何改进表示赞赏,谢谢!