none
tabla principal inner join primera historia RRS feed

  • Pregunta

  • hola grupo tengo la siguiente  problemática:
     quiero traer  los expedientes con la primera historia para mostrar en listado 
     uso las siguiente tablas :
     tabla:  expedientes:
            idexpte ....y otros datos
     historia :
     idhistoria fecha_insert  idexpte tipomovimiento  observacion


    la consulta que no me funciona es la siguiente : trato de cruzar por mínima fecha historia para obtener el primero pero algo estoy haciendo mal


     select * from expedientes E WITH (NOLOCK)
     inner join historia H WITH (NOLOCK)
          on  E.idexpte = H.idexpte
       inner join (select min(p.fecha_insert), p.idseg as minidseg from historia  as p 
               group by p.idexpte) primero 
    ON h idhis = primeros.minidseg

    gracias desde ya

       
    martes, 19 de noviembre de 2013 18:36

Respuestas

  • Veo que en la consulta interna estas agrupando por un campo que no esta en el SELECT si pruebas de la siguiente forma que te da

    select * from expedientes E WITH (NOLOCK)
     inner join historia H WITH (NOLOCK)
          on  E.idexpte = H.idexpte
       inner join (select min(p.fecha_insert), p.idseg as minidseg from historia  as p 
               group by p.idseg) primero 
    ON h idhis = primeros.minidseg


    Harol Perez

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 19:34
  • Usa el operador APPLY y trae la primera fila del historial que corresponde a cada expediente.

    select E.*, F.*
    from expedientes as E outer apply
    (
    select top (1) H.*
    from historia as H
    where H.idexpte = E.idexpte
    order by H.fecha_insert
    ) as F;


    AMB

    Some guidelines for posting questions...

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 19:46
  • Otra opcion seria unir ambas tablas y enumerar las filas para luego traer la primera de cada grupo.

    with C1 as (
    select A.*, B.*, row_number() over(partition by idexpte order by A.idexpte, B.fecha_insert) as rn
    from expedientes as A left outer join historia as B on A.idexpte = B.idexpte
    )
    select *
    from C1
    where rn =1;

    He usado un OUTER JOIN porque no se si puedes tener algun expediente sin historia y todavia verlo en el resultado.

    Dependera del # de expedientes y cuanta historia promedio se tenga para una solucion u otra prevalezca en cuanto a desempeño. Te toca a ti hacer la prueba y ver cual se adapta mejor a tu ambiente.


    AMB

    Some guidelines for posting questions...

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 20:57

Todas las respuestas

  • Prueba eliminando el primer INNER JOIN de la siguiente forma

    select * from expedientes E WITH (NOLOCK)
    inner join (select min(p.fecha_insert), p.idseg as minidseg from historia  as p 
               group by p.idexpte) primero ON h idhis = primeros.minidseg
    


    Harol Perez

    martes, 19 de noviembre de 2013 19:05
  • Gracias por contestar

    pasa que necesito cruzar por  la tabla historia  que tengo varios datos ahi , encima en el inner join lo cruzas por historia en el ultimo on

     primero ON h idhis = primeros.minidseg

    select * from expedientes E WITH (NOLOCK)
    inner join (select min(p.fecha_insert), p.idseg as minidseg from historia  as p 
               group by p.idexpte) primero ON h idhis = primeros.minidseg


    martes, 19 de noviembre de 2013 19:15
  • Veo que en la consulta interna estas agrupando por un campo que no esta en el SELECT si pruebas de la siguiente forma que te da

    select * from expedientes E WITH (NOLOCK)
     inner join historia H WITH (NOLOCK)
          on  E.idexpte = H.idexpte
       inner join (select min(p.fecha_insert), p.idseg as minidseg from historia  as p 
               group by p.idseg) primero 
    ON h idhis = primeros.minidseg


    Harol Perez

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 19:34
  • Usa el operador APPLY y trae la primera fila del historial que corresponde a cada expediente.

    select E.*, F.*
    from expedientes as E outer apply
    (
    select top (1) H.*
    from historia as H
    where H.idexpte = E.idexpte
    order by H.fecha_insert
    ) as F;


    AMB

    Some guidelines for posting questions...

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 19:46
  • no tengo acceso a bd, ahora cree tablas temporales  para reproducir lo mismo

    DECLARE @EXPEDIENTE table(
        idexpte int NOT NULL,
        descripcion varchar(200)
      );
    
    
    DECLARE @HISTORIA table(
        idhis int NOT NULL,
        idexpte int NOT NULL,
        observacion varchar(200),
        fecha_insert datetime 
      );
    
    insert into @EXPEDIENTE values (1,'expe 1');
    insert into @EXPEDIENTE values (2,'expe 2');
    
    insert into @HISTORIA values ( 1,1,'obser 1',' 20130318');
    insert into @HISTORIA values (2,1,'obser 2',' 20131119');
    
    SELECT * from @EXPEDIENTE
    	
    SELECT * from @HISTORIA
    	
    	
    	
    	
     select * from @EXPEDIENTE E 
    		  inner join @HISTORIA H 
    		       on  E.idexpte = H.idexpte
    	      inner join (select min(p.fecha_insert), p.idhis as midhis, p.idexpte as midexpe from @HISTORIA  as p 
    				            group by p.idexpte,p.idhis) primero 
    							 ON idhis = primero.midhis
    
    el error es este Mens. 8155, Nivel 16, Estado 2, Línea 32
    No column name was specified for column 1 of 'primero'.

    martes, 19 de noviembre de 2013 19:59
  • gracias no vi tu post , no conozco apply voy a  probar ::), muy bueno  , seria lo mismo si hago con inner join a nivel rendimiento?
    martes, 19 de noviembre de 2013 20:01
  • Otra opcion seria unir ambas tablas y enumerar las filas para luego traer la primera de cada grupo.

    with C1 as (
    select A.*, B.*, row_number() over(partition by idexpte order by A.idexpte, B.fecha_insert) as rn
    from expedientes as A left outer join historia as B on A.idexpte = B.idexpte
    )
    select *
    from C1
    where rn =1;

    He usado un OUTER JOIN porque no se si puedes tener algun expediente sin historia y todavia verlo en el resultado.

    Dependera del # de expedientes y cuanta historia promedio se tenga para una solucion u otra prevalezca en cuanto a desempeño. Te toca a ti hacer la prueba y ver cual se adapta mejor a tu ambiente.


    AMB

    Some guidelines for posting questions...

    • Marcado como respuesta sebastian viga martes, 19 de noviembre de 2013 22:22
    martes, 19 de noviembre de 2013 20:57
  • Gracias Hunchback otra vez  muy buenas las soluciones funciona las dos muy bien

    Saludos

     

    martes, 19 de noviembre de 2013 22:21