Ir al contenido



Foto

Seleccionar últimos registros de una Tabla


  • Por favor identifícate para responder
30 respuestas en este tema

#1 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 09:13

No creí que llegaría a este estado pero tengo bastante oxidada mi cabeza con SQL, y ni que decir... con Access.

Verán estoy haciendo una base de datos para mi viejo para su trabajo, y llegué a un punto en que debo hacer una consulta e informe que me ha roto la cabeza.
Tengo las siguientes tablas:
Expedientes -1---M- MovimientosEstadosExpediente -M---1- EstadoExpte

La tabla Movimientos contiene los campos
IDMovimiento (PK)
ExpteID (FK > Expedientes.IDExpediente)
EstadoID (FK > EstadoExpteIDEstado)
Fecha
Observaciones

La tabla Expedientes contiene
IDExpediente (FK)
Código
Número
Descripción
...

La tabla EstadoExpte contiene
IDEstado (OK)
Nombre

Por naturaleza del problema no es posible hacer que Código y/o Número fueran una PK. Necesariamente se debe hacer uso de esa clave artificial ID. Ya que código es una nomeclatura para identificar una zona y el número a los catrastos. Y como es de esperar hay diversas combinaciones aceptables de éstos.

¿Que necesito? Realizar una consulta que me extraiga el último estado de cada expediente. Es decir esto:

CodExpte - NumExpte - DescripcionExpte - UltimoEstado - FechaUltimoEstado

Por tanto si para el Expte ID 10 (por dar un número) tuviera 3 movimientos ingresados (12/09/14, 26/07/14, 03/10/14), me regresara aquel correspondiente a de la última fecha (03/10/14). Y así por cada expediente.

Ya tengo el historial completo, lo que no logro coordinar es mi cerebro para que arme esta consulta en particular. Y el asistente de consultas de Access no me sabe entender. Empleo Access 2010.

Una guía muchachos.

Que mal hace la falta de práctica. Ya ni SQL recuerdo.  :

Saludos,
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.604 mensajes
  • LocationMéxico

Escrito 03 septiembre 2014 - 09:32

Una idea rápida y que puede no funcionar  8-|

Ordena descendente y obten sólo el First 1  *-)

Saludos

Edito, no va a funcionar :D :D :D
  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 09:36

Una idea rápida y que puede no funcionar  8-|

Ordena descendente y obten sólo el First 1  *-)

Saludos

Edito, no va a funcionar :D :D :D

Vamos amigo, tu puedes... Intento N° 2. Esta consulta tiene que salir... a ver las cabezas porque yo evidentemente no tengo.

Saludos,
  • 0

#4 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.484 mensajes
  • LocationMexico City

Escrito 03 septiembre 2014 - 09:37

Porqué no ?  *-)

Saludox ! :)
  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 09:39

Porqué no ?  *-)

Saludox ! :)

Porque el FIRTS 1 va a ser que se quede en el 1er expediente. Y yo necesito que por cada expediente me traiga el último movimiento registrado.

Saludos,
  • 0

#6 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.604 mensajes
  • LocationMéxico

Escrito 03 septiembre 2014 - 09:41

Obteniendo el max(fecha)  *-)



sql
  1. SELECT
  2.   IDMovimiento,
  3.   ExpteID,
  4.   EstadoID,
  5.   MAX(Fecha)
  6.  
  7. FROM TU_TABLA
  8. GROUP BY 1,2,3



Saludos

  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 09:50

Obteniendo el max(fecha)  *-)



sql
  1. SELECT
  2.   IDMovimiento,
  3.   ExpteID,
  4.   EstadoID,
  5.   MAX(Fecha)
  6.  
  7. FROM TU_TABLA
  8. GROUP BY 1,2,3



Saludos


No funciona  :(

Parece simple el problema pero rompe cabeza.
Saludos,
  • 0

#8 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.484 mensajes
  • LocationMexico City

Escrito 03 septiembre 2014 - 09:50


Porqué no ?  *-)

Saludox ! :)

Porque el FIRTS 1 va a ser que se quede en el 1er expediente. Y yo necesito que por cada expediente me traiga el último movimiento registrado.

Saludos,


Obviamente tendrías que acomodarlo de manera descendente ;)... así tendrás el último...

Ahora obviamente tienes que especificar qué movimiento necesitas, si no, te pondrá el último registro de todos... puedes hacer dos consultas anidadas ;)

Saludox ! :)
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.604 mensajes
  • LocationMéxico

Escrito 03 septiembre 2014 - 09:53


Obteniendo el max(fecha)  *-)



sql
  1. SELECT
  2.   IDMovimiento,
  3.   ExpteID,
  4.   EstadoID,
  5.   MAX(Fecha)
  6.  
  7. FROM TU_TABLA
  8. GROUP BY 1,2,3



Saludos


No funciona  :(

Parece simple el problema pero rompe cabeza.
Saludos,


Supuse que los primeros tres datos serían iguales, porque debería de funcionar, a mi me funcionó.  ^o|

Saludos
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 09:54



Porqué no ?  *-)

Saludox ! :)

Porque el FIRTS 1 va a ser que se quede en el 1er expediente. Y yo necesito que por cada expediente me traiga el último movimiento registrado.

Saludos,


Obviamente tendrías que acomodarlo de manera descendente ;)... así tendrás el último...

Ahora obviamente tienes que especificar qué movimiento necesitas, si no, te pondrá el último registro de todos... puedes hacer dos consultas anidadas ;)

Saludox ! :)


Ummm. ¿Como sería más o menos? Estuve pensando en buscarle la vuelta por consulta anidada pero no concebí la forma.

Saludos,
  • 0

#11 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.484 mensajes
  • LocationMexico City

Escrito 03 septiembre 2014 - 09:59

Algo así: (perdón por no respetar la estructura, pero la idea es esa)



sql
  1. SELECT  movs.id_movimiento,
  2.           ( SELECT FIRST 1 aux.fecha_movimiento
  3.               FROM tabla_movimientos aux
  4.             WHERE aux.id_movimiento = movs.id_movimiento
  5.             ORDER BY aux.fecha_movimiento DESC ) fecha_movimiento
  6.   FROM tabla_movimientos movs



Se me ocurre que así podría ser  8-|

Saludox ! :)
  • 0

#12 Fenareth

Fenareth

    Advanced Member

  • Administrador
  • 3.484 mensajes
  • LocationMexico City

Escrito 03 septiembre 2014 - 10:02

He modificado mi penúltimo mensaje, con un ajuste...

Saludox ! :)
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 10:03

Supuse que los primeros tres datos serían iguales, porque debería de funcionar, a mi me funcionó.  ^o|

Saludos

Pues no son iguales.
Código y Número pueden variar. En realidad para un diseño más exquisito debiera haber una tabla más pero ya era bastante complicado. Te explico, en realidad el número del expediente debiera ser el ID, el asunto es que puede tenerse el mismo numero de expediente pero asociado a otro código. Y para un código en particular van a ver muchos. Podría hacerse una clave compuesta pero aquí nos manejamos mayormente con expedientes de una zona en particular y para males resulta ser que en ocasiones el código no es conocido y debemos recuperar o esperar a que el organismo controlador nos pase estos valores.
Todo esto llevo a que se disponga de 2 campos.
Es en realidad una relación (M:M) entre Código y Número pero para hacerlo más manejable es preferible llevarlo así.
Por ejemplo 18-12345 es uno, pero puede haber un 12345 en codigo 23.

¿Me explico?

Saludos,
  • 0

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 10:07

Algo así: (perdón por no respetar la estructura, pero la idea es esa)



sql
  1. SELECT  movs.id_movimiento,
  2.           ( SELECT FIRST 1 aux.fecha_movimiento
  3.               FROM tabla_movimientos aux
  4.             WHERE aux.id_movimiento = movs.id_movimiento
  5.             ORDER BY aux.fecha_movimiento DESC ) fecha_movimiento
  6.   FROM tabla_movimientos movs



Se me ocurre que así podría ser  8-|

Saludox ! :)

En un rato pruebo. Podría funcionar.

Saludos,
  • 0

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 10:43

Maldito Access.  8o|
Gaby, recibo como error "Ha intentato ejecutar una consulta que no incluye la expresión especificada "Aux.Fecha_movimiento" como parte de una función de agregado".  ^o|

EDITO: Ya vi el error, era reemplazar ORDER BY 1 en lugar de llamarlo por nombre.

Pero si bien ahora no recibo el error, sigo recibiendo todos los registros.  :|

Saludos,
  • 0

#16 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.133 mensajes

Escrito 03 septiembre 2014 - 11:14

La siguiente consulta te devuelve lo que buscas.



delphi
  1. SELECT Expedientes.Codigo, Expedientes.Numero, Expedientes.Descripcion, Estados.Estado AS ULTIMO_ESTADO, movimientos.Fecha AS ULTIMA_FECHA_ESTADO
  2. FROM Estados INNER JOIN (Expedientes INNER JOIN movimientos ON Expedientes.IdExpediente = movimientos.ExpteId) ON Estados.idEstado = movimientos.EstadoId
  3.  
  4. WHERE MOVIMIENTOS.IDMOVIMIENTO IN(SELECT Max(MOVIMIENTOS.IDMOVIMIENTO) AS MáxDeIDMOVIMIENTO
  5. FROM MOVIMIENTOS
  6. GROUP BY MOVIMIENTOS.EXPTEID;)



La primera parte puedes organizarla a tu gusto, la importante es la segunda que es la que devuelve los ids necesarios en la consulta.

Saludos.
  • 0

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 11:22

Por si le resulta de ayuda y orientación. Les dejo la consulta del historial completo:



sql
  1. SELECT TablaExptes.ExpteCod AS Código, TablaExptes.ExpteNro AS Número, TablaExptes.Descripción AS Descripción, TablaEstadosExpte.Nombre AS Estado, TablaMovimientosExptes.FechaRevision AS Fecha, TablaMovimientosExptes.Observaciones AS Observaciones
  2. FROM TablaExptes INNER JOIN (TablaEstadosExpte INNER JOIN TablaMovimientosExptes ON TablaEstadosExpte.[IDEstado] = TablaMovimientosExptes.[EstadoID]) ON TablaExptes.[IDExpte] = TablaMovimientosExptes.[ExpteID]
  3. ORDER BY TablaExptes.ExpteCod, TablaExptes.ExpteNro, TablaMovimientosExptes.FechaRevision DESC;



Bueno, similar a eso, lo que ando buscando es quedarme solamente con el movimiento fechado.

Gracias Wilson por participar. Voy a probar tu consulta a ver que resulta.
Les agradezco a todos su colaboración y estar robándoles el tiempo.

Saludos,
  • 0

#18 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.940 mensajes
  • LocationArgentina

Escrito 03 septiembre 2014 - 12:07

Wilson, tu consulta da error de sintaxis en JOIN y señala el error sobre el campo ULTIMA_FECHA_ESTADO. Algo raro por lo que a la vista todo induce a que está bien.
Probando variaciones menores de los campos, como por ejemplo sacándolo a ese, sigue con errores de JOIN. Y ahora señala como culpable a la tabla Movimientos justo delante del INNER JOIN.

Cosa mandinga  :| Examino donde está la metida de pata y no le veo un porqué.

Saludos,
  • 0

#19 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 804 mensajes
  • LocationMisiones, Argentina

Escrito 03 septiembre 2014 - 12:45

Desde la tabla de movimientos obtener el último expediente ordenando en forma descendente por día de movimiento y obteniendo solo el ID del expediente.
A partir de esta lista seleccionar los expedientes y mediante un JOIN obtener los estados.

Esa se supone es la solución, pero no se si puede funcionar en Access.

También tengo mi lío en la cabeza como para escribir la sentencia.
SELECT BLA BLA BLA FROM EXPEDIENTES INNER JOIN ESTADOS FROM SELECT DISTINCT 1 IDEXP ORDER BY DIAMODIF DESC ... FROM MODIFICACION

Perdón esa es mi idea, me complica no tener a mano los nombres de los campos y las tablas, ya que al contestar no puedo ver el mensaje original.

Salufos.
  • 0

#20 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.133 mensajes

Escrito 03 septiembre 2014 - 01:06

Wilson, tu consulta da error de sintaxis en JOIN y señala el error sobre el campo ULTIMA_FECHA_ESTADO. Algo raro por lo que a la vista todo induce a que está bien.
Probando variaciones menores de los campos, como por ejemplo sacándolo a ese, sigue con errores de JOIN. Y ahora señala como culpable a la tabla Movimientos justo delante del INNER JOIN.

Cosa mandinga  :| Examino donde está la metida de pata y no le veo un porqué.

Saludos,


La acabo de probar en Access  2010 y trabaja perfectamente,  adjunto db de ejemplo.



delphi
  1. SELECT Expedientes.Codigo, Expedientes.Numero, Expedientes.Descripcion, Estados.Estado AS ULTIMO_ESTADO, movimientos.Fecha AS ULTIMA_FECHA_ESTADO
  2. FROM Estados INNER JOIN (Expedientes INNER JOIN movimientos ON Expedientes.IdExpediente = movimientos.ExpteId) ON Estados.idEstado = movimientos.EstadoId
  3.  
  4. WHERE MOVIMIENTOS.IDMOVIMIENTO IN(SELECT Max(MOVIMIENTOS.IDMOVIMIENTO) AS MáxDeIDMOVIMIENTO
  5. FROM MOVIMIENTOS
  6. GROUP BY MOVIMIENTOS.EXPTEID;);



Revisa algún paréntesis, alguna coma, algún nombre de campo o algún nombre de  tabla. Igual la primera parte puedes hacerla a gusto, la que tiene la crema del asunto es la que está después del WHERE, que es la que devuelve los IDS de los últimos movimientos de cada expediente.

Saludos
  • 0