Me gustaría encontrar el primer "espacio" en una columna de contador en una tabla SQL. Por ejemplo, si hay valores 1, 2, 4 y 5, me gustaría averiguar 3.
Por supuesto, puedo ordenar los valores y revisarlos manualmente, pero me gustaría saber si habría una manera de hacerlo en SQL.
Además, debería ser SQL bastante estándar, trabajando con diferentes DBMS.
sql
gaps-and-islands
Touko
fuente
fuente
LAG(id, 1, null)
función conOVER (ORDER BY id)
cláusula.Respuestas:
En
MySQL
yPostgreSQL
:En
SQL Server
:En
Oracle
:ANSI
(funciona en todas partes, menos eficiente):Sistemas que admiten funciones de ventana deslizante:
fuente
URL
también, aunque creo que puede estar codificada en QR.[1, 2, 11, 12]
, entonces esto solo lo encontraría3
. Lo que me encantaría encontrar es 3-10 en su lugar, básicamente el principio y el final de cada hueco. Entiendo que podría tener que escribir mi propio script de Python que aproveche SQL (en mi caso MySql), pero sería bueno si SQL pudiera acercarme a lo que quiero (tengo una tabla con 2 millones de filas que tiene espacios, así que tendré que cortarlo en trozos más pequeños y ejecutar algo de SQL en él). Supongo que podría ejecutar una consulta para encontrar el inicio de una brecha, luego otra para encontrar el final de una brecha, y luego "fusionar ordenando" las dos secuencias.NULL
, no0
, si la mesa está vacía. Esto es cierto para todas las bases de datos.Todas sus respuestas funcionan bien si tiene un primer valor de identificación = 1; de lo contrario, esta brecha no se detectará. Por ejemplo, si los valores de identificación de su tabla son 3,4,5, sus consultas devolverán 6.
Hice algo como esto
fuente
Realmente no existe una forma SQL extremadamente estándar de hacer esto, pero con alguna forma de cláusula de limitación puede hacerlo
(MySQL, PostgreSQL)
o
(Servidor SQL)
o
(Oráculo)
fuente
Lo primero que me vino a la cabeza. No estoy seguro de si es una buena idea seguir este camino, pero debería funcionar. Suponga que la tabla es
t
y la columna esc
:Editar: Este puede ser un tic más rápido (¡y más corto!):
fuente
LEFT OUTER JOING t2
requeriría que tuvieras unat2
mesa, que es solo un alias.Esto funciona en SQL Server; no se puede probar en otros sistemas, pero parece estándar ...
También puede agregar un punto de partida a la cláusula where ...
Entonces, si tuviera 2000, 2001, 2002 y 2005 donde 2003 y 2004 no existían, regresaría 2003.
fuente
La siguiente solución:
Numera las filas ordenadas secuencialmente en la cláusula " con " y luego reutiliza el resultado dos veces con una combinación interna en el número de fila, pero compensada por 1 para comparar la fila anterior con la fila posterior, buscando ID con un espacio mayor que 1. Más de lo solicitado pero de mayor aplicación.
La consulta interna produce:
La consulta externa produce:
fuente
Unión interna a una vista o secuencia que tiene todos los valores posibles.
¿Incapaz? Hacer una mesa. Siempre mantengo una mesa simulada solo para esto.
Luego,
fuente
por
PostgreSQL
Un ejemplo que hace uso de una consulta recursiva.
Esto podría ser útil si desea encontrar un espacio en un rango específico (funcionará incluso si la tabla está vacía, mientras que los otros ejemplos no)
fuente
Mi conjetura:
fuente
Este da cuenta de todo lo mencionado hasta ahora. Incluye 0 como punto de partida, que será predeterminado si tampoco existen valores. También agregué las ubicaciones apropiadas para las otras partes de una clave de varios valores. Esto solo se ha probado en SQL Server.
fuente
Escribí una forma rápida de hacerlo. No estoy seguro de que sea el más eficiente, pero hace el trabajo. Tenga en cuenta que no le dice el espacio, pero le dice la identificación antes y después del espacio (tenga en cuenta que el espacio puede ser de varios valores, por ejemplo, 1,2,4,7,11, etc.)
Estoy usando sqlite como ejemplo
Si esta es la estructura de tu mesa
y estas son tus filas
La consulta es
https://gist.github.com/wkimeria/7787ffe84d1c54216f1b320996b17b7e
fuente
fuente
Aquí hay una solución SQL estándar que se ejecuta en todos los servidores de bases de datos sin cambios:
Ver en acción para;
fuente
También funciona para tablas vacías o con valores negativos. Solo probado en SQL Server 2012
fuente
Si usa Firebird 3, esto es más elegante y simple:
fuente
fuente
Encontré que la mayoría de los enfoques se ejecutan muy, muy lentamente
Supongo que la secuencia comienza en "1".mysql
. Aquí está mi solución paramysql < 8.0
. Probado en registros de 1 millón con un espacio cerca del final de ~ 1 segundo para terminar. No estoy seguro de si se ajusta a otros sabores de SQL.fuente
Si su contador comienza desde 1 y desea generar el primer número de secuencia (1) cuando está vacío, aquí está el fragmento de código corregido de la primera respuesta válida para Oracle:
fuente
fuente
Si los números en la columna son números enteros positivos (comenzando desde 1), aquí se explica cómo resolverlo fácilmente. (asumiendo que ID es el nombre de su columna)
fuente