Sqlite: iterando a través de subcadenas de un campo de cadena

Tengo un campo que contiene una cadena de números.

 "2002 2005 2001 2006 2008 2344"

Es preferible que asumamos que los espacios son las divisiones, de lo contrario, que tengan 4 caracteres cada uno.

Puedo seleccionar una subcadena:

SELECT substr(years,1,4)  FROM TABLE 

Pero no tengo idea de cómo verificar cada uno. Estoy tratando de encontrar la fila que contiene el número más cercano a 0.

y yo puedo ORDER BY y LIMIT 1.

preguntado el 31 de julio de 12 a las 11:07

Meh, si el campo en cuestión es lo suficientemente corto como para que no sea necesario realizar la operación de recuperación y matemática en la capa de base de datos (es decir, no resultará en una desaceleración), simplemente sacaría esto de la base de datos con un Cursor y usaría StringUtils#split(String) en eso. A partir de ahí usaría el devuelto. String[], introdúzcalo en un método Collections#sort() y recupere el valor más bajo. -

@OceanLife Desafortunadamente, hay demasiadas filas, y se necesitan más de 3 segundos para retirar todas las filas desde las que necesita verificar (ignorando el cálculo que luego se realiza). Donde como una declaración sql para obtener una fila sería mucho más rápido (instantánea). - Actualmente se ejecuta en código Java. -

Gorrón. Suena como un gran problema de un Google rápido. Esta pregunta tenía algunas ideas, pero todas se veían feas. La idea de llenar la columna de una tabla temporal con el valor de la fila y ordenarla podría funcionar. Sin embargo, no estoy seguro de la sobrecarga de limpiarlo entre cada fila. stackoverflow.com/questions/11155886/… -

¿Cuántos números hay en la cadena? ¿Cuál es el número máximo? -

@GordonLinoff Varía. Podría ser 1, podría ser 20. Y cada fila variará :| -

2 Respuestas

Esto parece FEO pero selecciona todo lo que necesita en una declaración de SQLlite. También puede hacer alguna optimización si asume que las fechas están en el intervalo actual, digamos 1900..2100. En este caso, puede cortar primero 2 selecciones B, C (B: 1 union 2) (C: 9 union 0 union 1)

 select years2,years from 
    (
    select i1||i2||i3||i4  as years2 from (select '0' as i1 
                   union all 
                   select '1' as i1
                   union all 
                   select '2' as i1
                   union all 
                   select '3' as i1
                   union all 
                   select '4' as i1 
                   union all 
                   select '5' as i1 
                   union all 
                   select '6' as i1
                   union all 
                   select '7' as i1
                   union all 
                   select '8' as i1
                   union all 
                   select '9' as i1) B, 
    (select '0' as i2 
                   union all 
                   select '1' as i2
                   union all 
                   select '2' as i2
                   union all 
                   select '3' as i2
                   union all 
                   select '4' as i2 
                   union all 
                   select '5' as i2 
                   union all 
                   select '6' as i2
                   union all 
                   select '7' as i2
                   union all 
                   select '8' as i2
                   union all 
                   select '9' as i2) C,
    (select '0' as i3 
                   union all 
                   select '1' as i3
                   union all 
                   select '2' as i3
                   union all 
                   select '3' as i3
                   union all 
                   select '4' as i3 
                   union all 
                   select '5' as i3 
                   union all 
                   select '6' as i3
                   union all 
                   select '7' as i3
                   union all 
                   select '8' as i3
                   union all 
                   select '9' as i3) D,
                  (select '0' as i4 
                   union all 
                   select '1' as i4
                   union all 
                   select '2' as i4
                   union all 
                   select '3' as i4 
                   union all 
                   select '4' as i4 
                   union all 
                   select '5' as i4 
                   union all 
                   select '6' as i4
                   union all 
                   select '7' as i4
                   union all 
                   select '8' as i4
                   union all 
                   select '9' as i4) E
    ) YearsAll

   left join YearsTable on (YearsTable.years like '%'||YearsAll.years2||'%')

    where YearsTable.years is not null

    order by years2 limit 1

Respondido 01 ago 12, 10:08

Ok, sigo la mayor parte, excepto la combinación izquierda. ¿El % no debería estar alrededor de yearsTable.years? Un buen esfuerzo. Podría intentarlo. +1 - soyGroot

YearsTable.years son sus cadenas largas ""2002 2005 2001 2006 2008 2344". YearsAll contiene todos los años desde 0000 hasta 9999. Entonces, para un ejemplo, registre esta condición: ' 2002 2005 2001 2006 2008 2344 ' like ' %2002% ' . Entonces es cierto si 2002 está en esta cadena. También he agregado el primer y el último espacio ' ' a los años tan pronto como la condición es ' %año% ' - valex

Condición de unión fija. No es necesario utilizar espacios adicionales en condición porque todos los dígitos tienen una longitud fija (4 caracteres) y están separados por espacios. valex

Puede usar una expresión de tabla común para dividir el año en la cadena de años y luego obtener el año más cercano a 0.

WITH split_years(year, years) AS (
    values(0, '2001 2002 2003 2004 2005 2006'||' ')
    UNION ALL SELECT
    cast(substr(years, 0, instr(years, ' ')) as int),
    substr(years, instr(years, ' ')+1)
    FROM split WHERE length(years)
) SELECT year FROM split_years WHERE year>0 ORDER BY year LIMIT 1;

La salida es:

2001

respondido 04 mar '19, 08:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.