Práctica de hebilla SQL (3)

Tabla de contenido

1. Números consecutivos (180)

Solución 1 (cuando el caso más variables personalizadas)

Solución 2 (idea especial)

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

Guess you like

Origin blog.csdn.net/weixin_53011574/article/details/131432923