ayudenme con un trabajo de base de datos porfavor

luis12011988

Bovino maduro
#1
Hola a todos, tengo un problema con un trabajo de base de datos I, espero me puedan ayudar.
tengo una tabla tb_documento en la cual dentro de ella se encuentra el campo id_tipdoc que me da a conocer el id del tipo documento que es, ya sea para boleta con id 00001, factura con id 00002 y recibo con id 00003.
Aqui les dejo las tablas a utilizar:

CREATE TABLE `tb_documento` (
`id_documento` varchar(8) NOT NULL,
`id_cliente` varchar(5) DEFAULT NULL,
`id_tipdoc` varchar(5) DEFAULT NULL,
`fecha` datetime DEFAULT NULL,
`ruc` varchar(8) DEFAULT NULL,
`monto_total` float DEFAULT NULL,
PRIMARY KEY (`id_documento`),
KEY `pk_id_cliente` (`id_cliente`),
KEY `pk_id_tipdoc` (`id_tipdoc`),
CONSTRAINT `pk_id_cliente` FOREIGN KEY (`id_cliente`) REFERENCES `tb_cliente` (`id_cliente`),
CONSTRAINT `pk_id_tipdoc` FOREIGN KEY (`id_tipdoc`) REFERENCES `tb_tipo_documento` (`id_tipdoc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `tb_tipo_documento` (
`id_tipdoc` varchar(5) NOT NULL,
`des_tipdoc` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id_tipdoc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Como veran en la tabla tb_documento se encuentra el id de la tabla tb_tipo_documento.
Como referencia me han dado esta sentencia:

SELECT year(fecha) as annio,
round(sum(case when id_tipdoc='00001' then monto_total end),2) as Boleta,
round(sum(case when id_tipdoc='00002' then monto_total end),2) as Factura,
round(sum(case when id_tipdoc='00003' then monto_total end),2) as Recibo
FROM tb_documento A
group by 1

y lo que se quiere es crear un procedimiento almacenado que cuando añada un nuevo tipo documento en su respectiva tabla, por ejemplo xxxx con id 00004 me salga una nueva columna con su monto total recaudado por año.

Aqui les dejo una imagen para que tengan una idea de lo que quiero hacer:

 

OLGUIVER

Bovino adolescente
#3
me gusta para hacerlo con un query dinamico, una funcion q te regrese dinamicamente el numero de columnas igual al tipo de documentos.

:mota:
 
#4
SELECT v.iddoc, SUM(DISTINCT v.Monto_total) AS monto FROM Ventas v GROUP BY v.idDoc

El resultado sería los códigos de documento y el monto de cada documento

--- ---

Si quieres ver nombre de documento, necesitas otra tabla con los nombres (create table docs ... id_tipdoc int, nomdoc nvarchar(30))

y luego

SELECT v.id_tipdoc, d.NomDoc, SUM(DISTINCT Monto_total) AS monto
FROM Ventas v
INNER JOIN docs d ON v.id_tipdoc = d.id_tipdoc
GROUP BY v.id_tipDoc, d.nombredoc
 
#5
Hola a todos, nuevamente, lamento la demora pero les quiero mencionar que el problema ya fue resuelto, aqui les dejo el codigo por si alguien logre necesitarlo:

DROP PROCEDURE IF EXISTS sp_ActualizaAos;
CREATE PROCEDURE sp_ActualizaAos()

BEGIN

DECLARE done INT DEFAULT 0;
DECLARE v_column_val INT;
DECLARE cur_years CURSOR FOR SELECT YEAR(fecha) FROM tb_documento group by YEAR(fecha);
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;



SET @QUERYYEARS = 'SELECT des_proveedor,';

OPEN cur_years;
REPEAT
FETCH cur_years into v_column_val;
IF NOT done THEN
SET @QUERYYEARS = CONCAT(@QUERYYEARS,'round(sum(case when year(fecha)=',CONVERT(v_column_val,CHAR(4)),' then monto_total end),2) as "',CONVERT(v_column_val,CHAR(4)),'",');
END IF;

UNTIL done END REPEAT;


CLOSE cur_years;

SET @TEMP = (SELECT SUBSTRING(@QUERYYEARS,1,LENGTH(@QUERYYEARS) - 1));

SET @QUERYYEARS = CONCAT(@TEMP,'FROM tb_documento A,tb_detalle_documento B,tb_producto C,tb_proveedor D
where A.id_documento=B.id_documento and B.id_producto=C.id_producto and
C.id_proveedor=D.id_proveedor
group by 1
order by 1');


PREPARE stmt from @QUERYYEARS;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


END;



call sp_ActualizaAos();
 
Arriba