Directorio de artículos
-
- 1. Introducción
-
- Caso: Basado en el requisito de "contar usuarios que han iniciado sesión por más de 3 días consecutivos".
-
- preparación de datos
- Opción 1: pensamiento convencional
-
- Para agrupar los datos user_id, ordene según la fecha de actividad del usuario
- Use la fecha de inicio de sesión y rn para encontrar date_sub, si las fechas de diferencia obtenidas son iguales, significa que estos dos días deben ser consecutivos
- Agrupados según user_id y diferencia de fecha sub_date, el número de inicios de sesión se cuenta (1) después de agrupar
- Solución 2: utilice funciones de retraso y adelanto
-
- Use las funciones LEAD y LAG para encontrar la fecha antes y después de 1 día
- Para cada usuario, si la diferencia entre la fecha del día anterior y el día siguiente y la fecha actual = 1, pertenece al inicio de sesión continuo.
- Para la agrupación de usuarios, la función dateiff calcula los días del tiempo máximo de actividad y el tiempo mínimo de actividad, y calcula los usuarios >=3 días
- Comparación del esquema 1 y el esquema 2
Directorio de artículos
- 1. Introducción
-
- Caso: Basado en el requisito de "contar usuarios que han iniciado sesión por más de 3 días consecutivos".
-
- preparación de datos
- Opción 1: pensamiento convencional
-
- Para agrupar los datos user_id, ordene según la fecha de actividad del usuario
- Use la fecha de inicio de sesión y rn para encontrar date_sub, si las fechas de diferencia obtenidas son iguales, significa que estos dos días deben ser consecutivos
- Agrupados según user_id y diferencia de fecha sub_date, el número de inicios de sesión se cuenta (1) después de agrupar
- Solución 2: utilice funciones de retraso y adelanto
-
- Use las funciones LEAD y LAG para encontrar la fecha antes y después de 1 día
- Para cada usuario, si la diferencia entre la fecha del día anterior y el día siguiente y la fecha actual = 1, pertenece al inicio de sesión continuo.
- Para la agrupación de usuarios, la función dateiff calcula los días del tiempo máximo de actividad y el tiempo mínimo de actividad, y calcula los usuarios >=3 días
- Comparación del esquema 1 y el esquema 2
- Como desarrollador de big data, nunca debe dejar atrás sus capacidades de SQL.
1. Introducción
Cuando trabajamos en ETL o en entrevistas de big data, el SQL a menudo se rompe a mano y el SQL común tiene problemas continuos de inicio de sesión. La pregunta general es "Estadísticas de XX que han iniciado sesión en XX durante N días consecutivos".
El editor está aquí hoy para presentar dos soluciones para que pueda manejar fácilmente estos problemas de SQL.
Muchas funciones de mysql8.x y Hive están básicamente satisfechas. En aras de la eficiencia y la conveniencia, aquí está mysql como ejemplo. Otro SQL es similar. Si tiene alguna pregunta, puede dejar un mensaje en el área de comentarios.
Caso: Basado en el requisito de "contar usuarios que han iniciado sesión por más de 3 días consecutivos".
preparación de datos
Ejecute el siguiente código en mysql para generar la tabla de datos correspondiente
-- ---------------------------- -- Table structure for user_activity -- ---------------------------- DROP TABLE IF EXISTS `user_activity`; CREATE TABLE `user_activity` ( `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `activity_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user_activity -- ---------------------------- INSERT INTO `user_activity` VALUES ('user1', '2023-03-01'); INSERT INTO `user_activity` VALUES ('user2', '2023-03-02'); INSERT INTO `user_activity` VALUES ('user3', '2023-03-03'); INSERT INTO `user_activity` VALUES ('user4', '2023-03-04'); INSERT INTO `user_activity` VALUES ('user1', '2023-03-08'); INSERT INTO `user_activity` VALUES ('user2', '2023-03-08'); INSERT INTO `user_activity` VALUES ('user5', '2023-03-08'); INSERT INTO `user_activity` VALUES ('user6', '2023-03-08'); INSERT INTO `user_activity` VALUES ('user3', '2023-03-09'); INSERT INTO `user_activity` VALUES ('user5', '2023-03-09'); INSERT INTO `user_activity` VALUES ('user6', '2023-03-09'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-09'); INSERT INTO `user_activity` VALUES ('user3', '2023-03-10'); INSERT INTO `user_activity` VALUES ('user5', '2023-03-10'); INSERT INTO `user_activity` VALUES ('user6', '2023-03-10'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-10'); INSERT INTO `user_activity` VALUES ('user5', '2023-03-11'); INSERT INTO `user_activity` VALUES ('user6', '2023-03-11'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-11'); INSERT INTO `user_activity` VALUES ('user6', '2023-03-12'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-12'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-13'); INSERT INTO `user_activity` VALUES ('user8', '2023-03-13'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-14'); INSERT INTO `user_activity` VALUES ('user8', '2023-03-14'); INSERT INTO `user_activity` VALUES ('user7', '2023-03-15'); INSERT INTO `user_activity` VALUES ('user8', '2023-03-15'); INSERT INTO `user_activity` VALUES ('user8', '2023-03-16');
SELECT * FROM `user_activity`
El resultado es el siguiente:
user1 2023-03-01 user2 2023-03-02 user3 2023-03-03 user4 2023-03-04 user1 2023-03-08 user2 2023-03-08 user5 2023-03-08 user6 2023-03-08 user3 2023-03-09 user5 2023-03-09 user6 2023-03-09 user7 2023-03-09 user3 2023-03-10 user5 2023-03-10 user6 2023-03-10 user7 2023-03-10 user5 2023-03-11 user6 2023-03-11 user7 2023-03-11 user6 2023-03-12 user7 2023-03-12 user7 2023-03-13 user8 2023-03-13 user7 2023-03-14 user8 2023-03-14 user7 2023-03-15 user8 2023-03-15 user8 2023-03-16
Opción 1: pensamiento convencional
- 1. Primero agrupe los datos user_id, ordénelos según la fecha de actividad del usuario
- 2. Use la fecha de inicio de sesión y rn para encontrar date_sub, si las fechas de diferencia obtenidas son iguales, significa que estos dos días deben ser consecutivos
- Por ejemplo, 1 de enero, 2 de enero y 3 de enero de 2023; las clasificaciones son 1, 2 y 3 respectivamente; ahora use la fecha: ¿la clasificación es igual al 31 de diciembre de 2022?
- 3. De acuerdo con la agrupación sub_fecha de ID de usuario y diferencia de fecha, el número de inicios de sesión se cuenta (1) después de la agrupación
Para agrupar los datos user_id, ordene según la fecha de actividad del usuario
select
user_id,
activity_date,
ROW_NUMBER() over(partition by user_id order by activity_date) as rn
from user_activity
Use la fecha de inicio de sesión y rn para encontrar date_sub, si las fechas de diferencia obtenidas son iguales, significa que estos dos días deben ser consecutivos
SELECT
user_id,
activity_date,
DATE_SUB(activity_date,INTERVAL rn DAY) as sub_date
from(
select
user_id,
activity_date,
ROW_NUMBER() over(partition by user_id order by activity_date) as rn
from user_activity
)t1
Agrupados según user_id y diferencia de fecha sub_date, el número de inicios de sesión se cuenta (1) después de agrupar
SELECT
user_id,
min(activity_date) as min_date,
max(activity_date) as max_date,
count(1) as login_times
from(
SELECT
user_id,
activity_date,
DATE_SUB(activity_date,INTERVAL rn DAY) as sub_date
from(
select
user_id,
activity_date,
ROW_NUMBER() over(partition by user_id order by activity_date) as rn
from user_activity
)t1
)t2
group by user_id,sub_date
having login_times>=3;
- De los resultados, se puede ver que los usuarios 5, 6, 7 y 8 han iniciado sesión durante 3 días consecutivos o más
Solución 2: utilice funciones de retraso y adelanto
- 1. Para cada ID de usuario, primero use las funciones de retraso y adelanto para encontrar la fecha del día anterior y el día posterior a la fecha actual
- 2. Para cada usuario, si la diferencia entre la fecha del día anterior y el día siguiente y la fecha actual = 1, pertenece al inicio de sesión continuo.
- Por ejemplo, 1 de enero, 2 de enero y 3 de enero de 2023, ahora use la fecha 2: la diferencia entre antes y después es 2-1 = 1, 3-2 = 1. Si el valor es 1 o no Paño de lana.
- 3. Para la agrupación de usuarios, la función dateiff calcula los días del tiempo máximo de actividad y el tiempo mínimo de actividad, y calcula los usuarios >=3 días
Use las funciones LEAD y LAG para encontrar la fecha antes y después de 1 día
select
user_id,
LAG(activity_date,1,activity_date) over(partition by user_id order by activity_date) as lag_login_date,
activity_date as current_login_date,
LEAD(activity_date,1,activity_date) over(partition by user_id order by activity_date) as lead_login_date
from user_activity
Para cada usuario, si la diferencia entre la fecha del día anterior y el día siguiente y la fecha actual = 1, pertenece al inicio de sesión continuo.
SELECT
user_id,
lag_login_date,
current_login_date,
lead_login_date
from(
select
user_id,
LAG(activity_date,1,activity_date) over(partition by user_id order by activity_date) as lag_login_date,
activity_date as current_login_date,
LEAD(activity_date,1,activity_date) over(partition by user_id order by activity_date) as lead_login_date
from user_activity
)t1
where datediff(current_login_date,lag_login_date)=1
and datediff(lead_login_date,current_login_date)=1;
Para la agrupación de usuarios, la función dateiff calcula los días del tiempo máximo de actividad y el tiempo mínimo de actividad, y calcula los usuarios >=3 días
SELECT
user_id,
min(activity_date) as min_date,
max(activity_date) as max_date,
count(1) as login_times
from(
SELECT
user_id,
activity_date,
DATE_SUB(activity_date,INTERVAL rn DAY) as sub_date
from(
select
user_id,
activity_date,
ROW_NUMBER() over(partition by user_id order by activity_date) as rn
from user_activity
)t1
)t2
group by user_id,sub_date
having login_times>=3;
Comparación del esquema 1 y el esquema 2
Solución 1, la idea es muy simple y más fácil de implementar Se puede completar simplemente al comprender la función de clasificación de ventanas y las capacidades básicas de SQL. En el nivel de dificultad
,
la opción 2 tiene una idea simple, pero es más difícil de implementar y requiere cierta comprensión y habilidad en la función de apertura de ventanas. dificultad alta