none
sql RRS feed

  • Pregunta

  • hola, consulta, tengo estas tablas

    REGISTRO
    ID-USUARIO-DIA SEMANA-HORAS

    PROYECTO
    ID-COMPAÑIA-NOMBRE PROYECTO

    USUARIO
    ID-NOMBRE

    COMPAÑIA
    ID-NOMBRE COMP

    y tengo que obtener nombre de trabajador, el proyecto en el que participa, la empresa y las horas totales, y tengo esta consulta:

    select usuario.descr as nombre, sum(WRKHRS) as horas_totales  
    from PRMREG as registro
    left join PRMUSER as usuario
    on registro.prmuser=usuario.prmuser

    el problema es que no se como hacer para que muestre el nombre de la empresa, o sea, si se como hacerlo, pero no se como agregar el codigo a la consulta. si pueidran ayudarme se los agradeceria

    lunes, 15 de abril de 2019 19:24

Todas las respuestas

  • Hola consulta1:

    No puedes, porque no tienes los datos normalizados.

    Te voy a dar unas cuantas lineas de ayuda, pero lo primero es que este no es el foro de Sql Server. Cuando tengas dudas, plantealas aqui (foro Sql Server)

    En cuanto a tu modelo de datos, y a lo que has planteado, es mucho mejor saber realmente que tipo de campos son los que trabajas. Yo te planteo el escenario, según lo que has puesto.

    Create table Registro (id int identity(1,1), usuario int, dia int, semana int, horas int);
    go
    Create table Proyecto (id int identity(1,1), compañia varchar(100), nombreProyecto varchar(100));
    go
    Create table Usuario (id int identity(1,1), nombre varchar(100));
    go
    Create table Compañia (id int identity(1,1), nombreCia varchar(100));
    go
    insert into Compañia (nombreCia)
    values
    ('Cia ejemplo');
    go
    insert into Usuario (nombre)
    values
    ('Juan'), ('Ana');
    go
    insert into Proyecto (compañia, nombreProyecto)
    values
    (1,'Proyecto 1'),
    (1,'Proyecto 2'),
    (2,'Proyecto 3'),
    (2,'Proyecto 4');
    go
    insert into Registro (usuario, dia, semana, horas)
    values
    (1,1,1,10),
    (1,1,2,10),
    (1,1,3,8),
    (1,1,4,10),
    (1,1,5,10),
    (1,1,6,10),
    (1,1,7,8),
    (1,2,8,10),
    (1,2,9,10),
    (1,2,10,8),
    (1,2,11,10),
    (1,2,14,10),
    (1,3,15,10),
    (1,3,16,8),
    (1,3,17,10),
    (2,1,1,10),
    (2,1,2,10),
    (2,1,3,8),
    (2,1,5,10),
    (2,1,7,8),
    (2,2,8,10),
    (2,2,9,10),
    (2,2,11,10),
    (2,2,14,10),
    (2,3,15,10),
    (2,3,16,8),
    (2,3,17,10);
    go
    

    Hasta aquí, he recreado las tablas y les he metido datos.

    Pero el problema es este.

    ;with cte as (
    Select SUM(horas) HorasUser, Usuario
    from Registro
    group by usuario
    )
    select * from cte c inner join Usuario u on c.usuario = u.id
    

    Esta consulta, es muy similar a lo que tu planteas, pero realizada con una tabla de expresión común

    Pero no hay manera de enlazarlo con proyecto. Te falta en la tabla de registro, un id de proyecto, porque así un operario, puede estar trabajando en dos proyectos a la vez, y entonces puede tener horas a cargo diferentes por proyecto, o incluso por empresa.

    Cambiamos el modelo.

    drop table if exists dbo.Registro;
    Create table Registro (id int identity(1,1), usuario int, dia int, semana int, horas int, idProyecto int);
    go
    insert into Registro (usuario, dia, semana, horas, idProyecto)
    values
    (1,1,1 ,10,1),
    (1,1,2 ,10,1),
    (1,1,3  ,8,1),
    (1,1,4 ,10,1),
    (1,1,5 ,10,1),
    (1,1,6 ,10,1),
    (1,1,7  ,8,1),
    (1,2,8 ,10,2),
    (1,2,9 ,10,2),
    (1,2,10 ,8,2),
    (1,2,11,10,2),
    (1,2,14,10,2),
    (1,3,15,10,2),
    (1,3,16 ,8,2),
    (1,3,17,10,2),
    (2,1,1 ,10,2),
    (2,1,2 ,10,2),
    (2,1,3  ,8,2),
    (2,1,5 ,10,2),
    (2,1,7  ,8,2),
    (2,2,8 ,10,2),
    (2,2,9 ,10,2),
    (2,2,11,10,2),
    (2,2,14,10,2),
    (2,3,15,10,2),
    (2,3,16 ,8,2),
    (2,3,17,10,2);
    

    La solución

    WITH cte
    	AS (SELECT SUM(horas) HorasUser
    		    , Usuario
    		    , idProyecto
    	    FROM   
    		    Registro
    	    GROUP BY usuario
    			 , idProyecto)
    	SELECT  c.HorasUser as HorasUsuarioProyecto
    		  ,c.idProyecto as idProyecto
    		  ,p.nombreProyecto as NomProyecto
    		  ,c.usuario as idUsuario
    		  ,u.nombre as NomUsuario
    		  ,a.nombreCia as Compañia
    	FROM   
    		cte c
    			INNER JOIN Usuario u ON c.usuario = u.id
    			INNER JOIN Proyecto p ON c.idProyecto = p.id
    			INNER JOIN Compañia a ON p.compañia = a.id;

    En el conjunto interior, realizo una suma agrupada de las horas, por usuario y proyecto.

    En la query resultante, lo relaciono con el resto de tablas para mostrar información.

    Como Juan ha trabajado en 2 proyectos, tiene horas aplicables a cada uno.

    Luego si quieres filtrar, por ejemplo por semana, dentro del conjunto cte, aplicas la restricción where y lo tienes solucionado.

    Datos

    lunes, 15 de abril de 2019 20:03
  • ok gracias por la ayuda
    martes, 16 de abril de 2019 12:45