我需要编写查询以找出新用户和普通用户。
新用户是那些uuid在table2
过去24小时内(从现在开始减去查询被触发的时间)出现的用户
普通用户是那些uuid在最后一天出现在table2
并且在过去3天内至少也出现过一次的人。
除此之外,只考虑id > 10
和ip != 2
的记录。
table1
是一个包含日期的临时表。我无法弄清楚如何通过连接来实现这一目标。请帮帮我。
+----+---------------------+------+------+ | id | ts | uuid | ip | +----+---------------------+------+------+ | 1 | 2010-01-10 00:00:00 | uid1 | 5 | | 2 | 2010-01-10 00:00:00 | uid2 | 14 | | 3 | 2010-01-10 00:00:00 | uid3 | 11 | | 4 | 2010-01-11 00:00:00 | uid4 | 16 | | 5 | 2010-01-11 00:00:00 | uid5 | 4 | | 6 | 2010-01-13 00:00:00 | uid6 | 2 | | 7 | 2010-01-10 00:00:00 | uid1 | 1 | | 8 | 2010-01-11 00:00:00 | uid2 | 10 | | 9 | 2010-01-12 00:00:00 | uid1 | 1 | | 10 | 2010-01-13 00:00:00 | uid4 | 1 | | 11 | 2010-01-09 21:00:00 | uid1 | 1 | | 12 | 2010-01-09 21:30:00 | uid1 | 2 | | 13 | 2010-01-10 05:00:00 | uid2 | 3 | | 14 | 2010-01-10 12:00:00 | uid1 | 1 | | 15 | 2010-01-10 12:00:00 | uid3 | 1 | | 16 | 2010-01-10 21:00:01 | uid1 | 7 | | 17 | 2010-01-11 01:00:00 | uid2 | 14 | | 18 | 2010-01-11 05:00:00 | uid2 | 11 | | 19 | 2010-01-11 17:59:00 | uid4 | 13 | | 20 | 2010-01-11 06:00:00 | uid5 | 12 | | 21 | 2010-01-11 18:01:00 | uid1 | 14 | | 22 | 2010-01-12 23:05:00 | uid4 | 17 | | 23 | 2010-01-13 12:01:23 | uid6 | 13 | +----+---------------------+------+------+ 23 rows in set (0.00 sec)
+------------+ | ts | +------------+ | 2010-01-10 | | 2010-01-11 | | 2010-01-12 | | 2010-01-13 | +------------+ 4 rows in set (0.00 sec)
+------------+-------+
| ts | users |
+------------+-------+
| 2010-01-10 | 3 |
| 2010-01-11 | 2 |
| 2010-01-12 | 0 |
| 2010-01-13 | 1 |
+------------+-------+
4 rows in set (0.00 sec)
DROP TABLE IF EXISTS `table1`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `table1` (
`ts` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `table1` VALUES ('2010-01-10'),('2010-01-11'),('2010-01-12'),('2010-01-13');
DROP TABLE IF EXISTS `table2`;
CREATE TABLE `table2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ts` datetime DEFAULT NULL,
`uuid` varchar(20) DEFAULT NULL,
`ip` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `table2` VALUES (1,'2010-01-10 00:00:00','uid1',5),(2,'2010-01-10 00:00:00','uid2',14),(3,'2010-01-10 00:00:00','uid3',11),(4,'2010-01-11 00:00:00','uid4',16),(5,'2010-01-11 00:00:00','uid5',4),(6,'2010-01-13 00:00:00','uid6',2),(7,'2010-01-10 00:00:00','uid1',1),(8,'2010-01-11 00:00:00','uid2',10),(9,'2010-01-12 00:00:00','uid1',1),(10,'2010-01-13 00:00:00','uid4',1),(11,'2010-01-09 21:00:00','uid1',1),(12,'2010-01-09 21:30:00','uid1',2),(13,'2010-01-10 05:00:00','uid2',3),(14,'2010-01-10 12:00:00','uid1',1),(15,'2010-01-10 12:00:00','uid3',1),(16,'2010-01-10 21:00:01','uid1',7),(17,'2010-01-11 01:00:00','uid2',14),(18,'2010-01-11 05:00:00','uid2',11),(19,'2010-01-11 17:59:00','uid4',13),(20,'2010-01-11 06:00:00','uid5',12),(21,'2010-01-11 18:01:00','uid1',14),(22,'2010-01-12 23:05:00','uid4',17),(23,'2010-01-13 12:01:23','uid6',13);
答案 0 :(得分:2)
您可以将表连接到自身,以搜索超过一天的同一用户的条目。当没有一天的匹配时,左连接表中的字段将为NULL。
例如:
select
YEAR(cur.ts) as year
, MONTH(cur.ts) as month
, DAY(cur.ts) as day
, case when old.uuid is null then 1 else 0 end as IsNewUser
, count(distinct cur.uuid) as Users
from table2 cur
left join table2 old
on cur.uuid = old.uuid
and old.ip <> 2
and old.id > 10
and cur.ts - old.ts > 1
where cur.ip <> 2
and cur.id > 10
group by year, month, day, IsNewUser
order by year, month, day, IsNewUser
答案 1 :(得分:1)
我对MySQL并不熟悉,但这就是我在Oracle中的表现:
SELECT uuid, 'NEW' as user_type FROM
(SELECT uuid, MAX(ts) as MAX_TS, MIN(ts) as MIN_TS
FROM TABLE2
WHERE ID > 10 AND
IP <> 2
GROUP BY uuid
HAVING MAX_TS > SYSTIMESTAMP - INTERVAL '1' DAY AND
MAX_TS = MIN_TS) nu
UNION ALL
SELECT DISTINCT uuid, 'REGULAR' as user_type FROM
(SELECT uuid, MAX(ts) as MAX_TS
FROM TABLE2
WHERE ID > 10 AND
IP <> 2
GROUP BY uuid) n
INNER JOIN (SELECT *
FROM TABLE2
WHERE ID > 10 AND
IP <> 2) t
ON (t.uuid = n.uuid)
WHERE n.MAX_TS > SYSTIMESTAMP - INTERVAL '1' DAY AND
t.ts < SYSTIMESTAMP - INTERVAL '1' DAY AND
t.ts > SYSTIMESTAMP - INTERVAL '3' DAY;
我在这里看不到TABLE1的用法。你需要使用它吗?
不知道MySQL是否支持SYSTIMESTAMP或INTERVAL构造。但是,希望这会为您提供一些想法。