Tabla de contenido
Solución 1 (cuando el caso más variables personalizadas)
Solución 3 (retraso, función de avance)
Solución 4 (función número_fila)
1. Números consecutivos (180)
superficie:Logs
+-------------+---------+ | Nombre de columna | Tipo | +-------------+---------+ | identificación | entero | | si varchar | +-------------+---------+ id es la clave principal de esta tabla.
Escriba una consulta SQL que encuentre todos los números que ocurren al menos tres veces seguidas.
Los datos de la tabla de resultados devueltos pueden estar en cualquier orden .
Ejemplo 1:
ingresar: Tabla de registros: +----+-----+ | eso | Hace | +----+-----+ | 1 | 1 | | 2 | 1 | | 3 | 1 | | 4 | 2 | | 5 | 1 | | 6 | 2 | | 7 | 2 | +----+-----+ producción: Tabla de resultados: +-----------------+ | números consecutivos | +-----------------+ | 1 | +-----------------+ Explicación: 1 es el único número que aparece al menos tres veces seguidas.
Solución 1 (cuando el caso más variables personalizadas)
Primero, se divide en dos partes. La primera parte es agregar un conteo a cada número y la segunda parte es deduplicar.
Aquí se usan dos variables personalizadas @pre y @count.Si agrega = directamente después de la variable personalizada, es un juicio, y si es: =, es una asignación. La declaración case when también se usa aquí, que es similar a if else en el código. uso:
CASO CUANDO condición ENTONCES resultado
[CUANDO... ENTONCES...]
DE LO CONTRARIO resultado
FIN
El código de implementación específico es el siguiente:
select distinct Num ConsecutiveNums
from(select Num ,
case
when @pre=Num then @count:=@count+1
when (@pre:=Num) is not null then @count:=1
end as count
from logs,(select @pre:=null,@count:=null) d
) t
where t.count>=3
Solución 2 (idea especial)
Al ver este tipo de solución en la solución de Likou, me siento muy novedoso. No esperaba escribirlo así, y la eficiencia es similar a la anterior. Filtre directamente tres números adyacentes e idénticos a la vez y luego elimine los duplicados.
SELECT DISTINCT
l1.Num AS ConsecutiveNums
FROM
Logs l1,
Logs l2,
Logs l3
WHERE
l1.Id = l2.Id - 1
AND l2.Id = l3.Id - 1
AND l1.Num = l2.Num
AND l2.Num = l3.Num
Solución 3 (retraso, función de avance)
En primer lugar, popularice el conocimiento, Lag/Lead(col,n,DEFAULT) se usa para contar el valor de la n-ésima fila hacia adelante o hacia atrás de la fila actual en la ventana
- El primer parámetro es el nombre de la columna,
- El segundo parámetro es la línea enésima siguiente/anterior (opcional, el valor predeterminado es 1),
- El tercer parámetro es el valor por defecto (cuando la línea n superior es NULL, se toma el valor por defecto, si no se especifica, es NULL)
Cabe señalar que el retraso obtiene los datos antes de la fila actual y el líder obtiene los datos después de la fila actual
select
distinct t.num as ConsecutiveNums
from
(
select
num,
lag(num, 1) over(order by id) as num1,
lag(num, 2) over(order by id) as num2
from Logs
) t
where t.num = t.num1 and t.num1 = t.num2
select
distinct t.num as ConsecutiveNums
from
(
select
num,
lag(num, 1) over(order by id) as num1,
lead(num, 1) over(order by id) as num2
from Logs
) t
where t.num = t.num1 and t.num1 = t.num2
Solución cuatro ( row_number函数
)
En MySQL, row_number()
la función se usa para particionar y se usa para generar uno para cada fila en el conjunto de resultados devuelto 序列号
(asignando un número de serie a la fila), y el primer número comienza con 1.
Lo siguiente también está escrito por un compañero de clase de Likou. Permítanme explicar brevemente la idea. Primero, se divide en dos partes. La primera parte es para averiguar los datos, y la segunda parte es responsable de la detección y la deduplicación. rn es para ordenar por id y agregar un número de serie. El autor debe considerar la situación en la que la id no es continua. id_rn se divide por num y se ordena por id para dar el número de serie. Luego, en el proceso de deduplicación, según la clasificación num y rn-id_rn, la segunda clasificación aquí puede no ser fácil de ver, porque los rn e id_rn anteriores se agrupan según id, por lo que si se restan, también son síncronos, y nuestro num no se repetirá, por lo que los datos agrupados de esta forma son correctos.
select
distinct t.num as ConsecutiveNums
from
(
select
id,
num,
row_number() over(order by id) as rn,
row_number() over(partition by num order by id) as id_rn
from Logs
) t
group by t.num, (t.rn - t.id_rn)
having count(*) >= 3