SELECT DISTINCT no acepta MEMO, que hago?

191 views
Skip to first unread message

Fernando Mora

unread,
May 29, 2020, 4:54:52 PM5/29/20
to Comunidad de Visual Foxpro en Español
Saludos comunidad!

Tengo una tabla nativa vfp9, con 3 campos carácter y un campo memo. Necesito depurar los valores repetidos, uso SELECT DISTINCT caracter1, caracter2, caracter3, memo FROM MiTabla INTO CURSOR CUR_REG, pero da error, dice que DISTINCT no acepta campo memo, por ahora estoy haciendo lo siguiente:

SELECT DISTINCT caractar1, caracter2, caracter3, CAST(SUBSTR(memo,1,250) AS C(250)) AS nota1, CAST(SUBSTR(memo,251,250) AS C(250)) AS nota2 FROM MiTabla INTO CURSOR CUR_REG 

Funciona, pero luego tengo que hacer un ALTER TABLE para unificar las columnas y volver transformarlo en campo memo. 

¿Como se puede hacer una consulta con DISTINCT incluyendo campo memo? ¿Alguien tiene una mejor idea?

Zarlu

unread,
May 29, 2020, 6:13:05 PM5/29/20
to Comunidad de Visual Foxpro en Español
Buenas tardes Fernando Mora!

SET ENGINEBEHAVIOR 70

En éste artículo mencionan al respecto

Suerte
zarlu
Chetumal, Quintana Roo, México

Carlos Miguel FARIAS

unread,
May 29, 2020, 6:17:09 PM5/29/20
to Grupo Fox
Es una limitación del motor de datos, no puedes indexar un memo, no puedes ordenar un memo (los SGBD creo que solo crean archivos invertidos sobre los memos, pero no sobre btree). La solución es como tu lo indicaste, o trabajar en varios pasos, creando una tabla de trabajo intermedia.
Aqui un algoritmo tentativo:
* creo una tabla de trabajo
CLEAR ALL
USE tu_tabla IN 0
SELECT C1, C2, C3, M1, 0 AS Q FROM tu_tabla INTO TABLE tabla_trabajo ORDER BY 1, 2, 3
CLOSE ALL
USE tabla_trabajo IN 0 ALIAS tt EXCLUSIVE
SELECT tt
* Analizo la tabla de trabajo para marcar cuales
* son registros con los 3 primeros campos repetidos
lnQ = 1 && cuenta != en 3 1°s campos
GO TOP && ubico 1° registro
SCATTER MEMVAR && tomo los campos
SCAN && recorro toda la tabla
   IF m.C1 != C1 OR m.C2 != C2 OR m.C3 != C3
      lnQ = lnQ + 1 && Si cambio algún campo Cn, incremento lnQ
      SCATTER MEMVAR && paso a memoria los nuevos valores
   ENDIF
   REPLACE Q WITH lnQ && cargo el valor del contador en Q
ENDSCAN
* recorro tabla de trabajo, que tiene un Q diferente para cada
* conjunto de registros que tienen iguales los campos Cn
lbRepite = .T. && señal que reviso
DO WHILE lbRepite && hago un bucle hasta que revise todo
   lbRepite = .F. && desactivo revisión
   SELECT tt
   GO TOP && voy al principio de la tabla
   SCATTER MEMO MEMVAR && tomo los datos
   SCAN FOR RECNO()>1 && recorro desde el segundo
      DO CASE
         CASE m.Q != Q && si contador distinto renuevo memoria
            SCATTER MEMO MEMVAR
         CASE m.M1 = M1 && si memo repetido
            DELETE && borro registro
            lbRepite = .T. && reactivo revision
      ENDCASE
   ENDSCAN
   PACK && quito registros borrados (son repetidos)
ENDDO && si hubo repetidos, analiza de nuevo
* S.E.u O. en tabla trabajo solo quedarían los distintos

Suerte y a probar
Saludos: Miguel

Libre de virus. www.avast.com

--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/7bd1353b-e594-4f1d-a8b2-50273051cf5f%40googlegroups.com.

Zarlu

unread,
May 29, 2020, 7:52:57 PM5/29/20
to Comunidad de Visual Foxpro en Español
Qué tal Fernando Mora!

Ya vi que SET ENGINEBEHAVIOR 70, si bien no marca error, no incluye el campo memo en el Distinct

A ver si esta idea sirve:
*a=campo carácter
*b=campo carácter
*c= campo memo

SET DELETED ON
USE C:\\tabla1.dbf IN 0 ALIAS orig

SELECT * FROM orig INTO CURSOR aa
SELECT a,b,c,.f. as Check1 FROM orig INTO CURSOR bb ReadWrite
SELECT orig
USE

SELECT aa
SCAN
    m=a+b+c
    SELECT bb
    LOCATE FOR a+b+c=m
    IF FOUND()
        Replace Check1 WITH .t.
    EndIf
ENDSCAN

SELECT a,b,c FROM bb WHERE Check1=.t.

SELECT bb
USe
SELECT aa
USE

Carlos Miguel FARIAS

unread,
May 30, 2020, 9:42:56 AM5/30/20
to Grupo Fox
Pregunta: si aa y bb son copias del original, aa y bb son iguales (salvo el campo agregado), cuando en bb haces un LOCATE, siempre va a encontrar un registro (el primero), entoces quedarían todos chequeados, a lo mejor, luego de encontrar el primero, debería buscar el segundo y sub siguiente y entonces si chequear esos.
O no entendí nada?
Probaste lo que pase?
Saludos: Miguel

--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.

Zarlu

unread,
May 30, 2020, 10:38:38 AM5/30/20
to Comunidad de Visual Foxpro en Español
Buenos días Miguel!

Si. Lo probé

El campo adicional del cursor bb inicia en .f.,  se localiza sólo el primer idéntico y se marca en .T., los demás idénticos no son localizados y quedan en .F..
El cursor final extrae unicamente los T.

Para el ejemplo los registros 1 y 2 son idénticos en sus 3 campos.
Adjunto código y tabla ejemplo

(curiosidades: el campo memo contiene un código musical válido)

Saludos igual Miguel
programa1.prg
tabla1.dbf
tabla1.FPT

Carlos Miguel FARIAS

unread,
May 30, 2020, 10:54:04 AM5/30/20
to Grupo Fox
Buena solución, lo razone al vesre.
La cuareterna me tiene locro (locro, si no te dicen que es, pensas que alguien vómito).
Como estoy en grupo de riesgo, en el trabajo me mandaron a trabajar en casa desde el 13 de marzo.
Por razones médicas tenía que caminar lo más (artrosis, artritis, colesterol, trastorno de sueño, etc.) nada grave porque el tratamiento es simple. Con la restricciones para salir, recién habilitaron caminatas la semana pasada.
Maginate. 🖖😁

--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.

Fernando Mora

unread,
May 30, 2020, 8:27:17 PM5/30/20
to Comunidad de Visual Foxpro en Español
Saludos Foxeros!

Gracias Miguel y Zarlu por compartir sus ideas, son geniales probé ambas y funcionan muy bien. Les comparto mi experiencia con este tema. Probé las recomendaciones de recorrer la tabla y todo bien, excepto por el tiempo que se tarda, probando los métodos de recorrer la tabla en una tabla con algo mas de 20 mil registro (la mas pequeña) se tardo cerca de 3 minutos, y usando el método que ya venía empleando, el SELECT DISTINCT y luego otra consulta para unir los campos carácter para volver armar el memo, se tarda 10 segundos. El resultado es de 15770 registros limpios. El problema con mi método de convertir el campo memo a carácter y luego volver a unirlo en campo memo es que en tablas de 1 millón y medio de registro explota Fox a los 16 minutos de procesar, me arroja el mensaje que el TEMP es demasiado grande. 

Entonces cambie de estrategia, los archivos que recibo, llegan en formato TXT, yo estaba usando el asistente para importar de Fox a DBF, entonces se me ocurrió hacer el proceso de depuración al momento de importar el TXT. Para esto hice mi propio código de importación, y emplee su sugerencia de guardar el Iden del registro y compararlo con el siguiente, ya que por suerte el TXT viene ordenado, y quedo perfecto. Se simplifico la tarea, ya no importo el texto, luego lo depuro y luego lo uno... lo estoy haciendo en un solo proceso todo y los resultados de tiempo son geniales. 
En archivos de 150 mil registro se tarda 2 minutos aproximadamente. En los archivos de 1,5 millones de registro se tarda 24 minutos (son dos de estos archivos enormes)

Saludos a todos y muchas gracias por su colaboración.

Fernando Mora.
Machala - Ecuador

Carlos Miguel FARIAS

unread,
May 31, 2020, 9:36:27 AM5/31/20
to Grupo Fox
Buenisimo!! Cada uno aportó un granito de arena, y construimos un meteorito que mató los dinosaurios 😁👍🖖

Libre de virus. www.avast.com

--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.

Luis suescún

unread,
May 31, 2020, 10:23:35 AM5/31/20
to publice...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages