Мне нужно написать запросы, чтобы найти новых пользователей и постоянных пользователей .
новые пользователи - это те, чей uuid появился за последние 24 часа (с этого момента минус время, когда запрос был запущен) в table2
и не был там раньше.
Обычные пользователи - это те, чей uuid появился в последний день table2
и был там хотя бы один раз за последние 3 дня.
В дополнение к этому будут рассматриваться только записи с id > 10
и ip != 2
.
table1
- временная таблица, содержащая даты. Я не могу понять, как этого добиться с помощью объединений. Помогите, пожалуйста.
Таблица 2
+----+---------------------+------+------+ | 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)
Таблица 1
+------------+ | ts | +------------+ | 2010-01-10 | | 2010-01-11 | | 2010-01-12 | | 2010-01-13 | +------------+ 4 rows in set (0.00 sec)
Вывод в случае новых пользователей взят в 18:00
+------------+-------+
| 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)
Дамп таблицы MySQL
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);
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
timestamp
на ts
(чтобы соответствовать оригиналу), я все равно получаю «ОШИБКА 1054 (42S22): Неизвестный столбец 'old.uuid' в 'списке полей'».
Я не очень хорошо знаком с 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. Надеюсь, это даст вам некоторые идеи.
Похожие вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.
table2
? Чтобы ограничить диапазон дат, для которых вы получите эту информацию?