I am trying to figure out a way to get opening balance, added_qty, reduced_qty and ending balance
for a specific period with 1 mysql query.
I have the following tables:
Explanations for Table Loadings
FIELD loading_type has the following meanings:
1 - initial loading / first time product qty added
2 - additional loading / added additional qty
3 - reduced qty / could be various reasons, for example reduced by order, than order_id > 0 | reduced becaused missing | reduced because broken
The next important thing here is that reduced by order qty must be taken only if paid_date from TABLE orders has date between given period
PLEASE NOTE that row #3 from Table Loadings was not taken in the expected results as reduce_qty because its order paid_date is in January next year so that's why its being counted in reduce_qty for January
and
The expected results should look like:
or if you change the period to
or if you change the period to
I have prepared a dump for sample databases as following:
--
-- Table structure for table `Loadings`
--
DROP TABLE IF EXISTS `Loadings`;
CREATE TABLE `Loadings` (
`id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`added_qty` int(11) NOT NULL DEFAULT 0,
`reduce_qty` int(11) NOT NULL DEFAULT 0,
`loading_type` int(1) NOT NULL DEFAULT 1,
`order_id` int(11) NOT NULL DEFAULT 0,
`added_date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `Loadings` VALUES(1, 4, 3, 0, 1, 0, '2020-12-03 08:46:40');
INSERT INTO `Loadings` VALUES(2, 4, 1, 0, 2, 0, '2020-12-15 08:46:40');
INSERT INTO `Loadings` VALUES(3, 4, 0, 1, 3, 1, '2020-12-16 08:46:40');
INSERT INTO `Loadings` VALUES(4, 4, 0, 2, 3, 2, '2020-12-21 08:46:40');
INSERT INTO `Loadings` VALUES(5, 4, 2, 0, 2, 0, '2021-01-05 08:46:40');
INSERT INTO `Loadings` VALUES(6, 4, 0, 1, 3, 3, '2021-01-06 08:46:40');
ALTER TABLE `Loadings` ADD PRIMARY KEY (`id`);
ALTER TABLE `Loadings` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
COMMIT;
--
-- Table structure for table `demo_orders`
--
CREATE TABLE `demo_orders` (
`id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`order_status` varchar(20) NOT NULL,
`paid_date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `demo_orders` VALUES(1, 4, 'finished', '2021-01-05 08:46:40');
INSERT INTO `demo_orders` VALUES(2, 4, 'finished', '2020-12-22 08:46:40');
INSERT INTO `demo_orders` VALUES(3, 4, 'finished', '2021-01-05 08:46:40');
ALTER TABLE `demo_orders` ADD PRIMARY KEY (`id`);
ALTER TABLE `demo_orders` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
So far I started with this query:
select concat("Opening balance: ",
sum(added_qty-reduce_qty)) as opening from Loadings where product_id = "4" and
month(added_date) = month( date_sub("2021-02-01", interval day("2021-02-01")+1 day) ) and
year(added_date) = year( date_sub("2021-02-01", interval day("2021-02-01")+1 day) )
union all select concat("Debit: ", sum(reduce_qty)) as debit from Loadings where product_id = "4" and
month(added_date) = month( date_sub("2021-02-01", interval day("2021-02-01")+1 day) ) and
year(added_date) = year( date_sub("2021-02-01", interval day("2021-02-01")+1 day) )
union all select concat("Credit: ", sum(added_qty)) as credit from Loadings where product_id = "4" and
month(added_date) = month( date_sub("2021-02-01", interval day("2021-02-01")+1 day) ) and
year(added_date) = year( date_sub("2021-02-01", interval day("2021-02-01")+1 day) );
but the customer added a requirement that orders that not paid between the period date must not counted and this totally confused me how the query should looks like..
AT this point the above query seems very poor approach but I added because #Shadow suggested to demponstrate some query attempt..
Any help highly appreciated !
i have got the below query which references couple of views 'goldedRunQueries' and 'currentGoldMarkings'. My issue seems to be from the view that is referred in the subquery - currentGoldMarkings. While execution, MySQL first materializes this subquery and then implements the where clauses of 'queryCode' and 'runId', which therefore results in execution time of more than hour as the view refers tables that has got millions of rows of data. My question is how do I enforce those two where conditions on the subquery before it materializes.
SELECT goldedRunQueries.queryCode, goldedRunQueries.runId
FROM goldedRunQueries
LEFT OUTER JOIN
( SELECT measuredRunId, queryCode, COUNT(resultId) as c
FROM currentGoldMarkings
GROUP BY measuredRunId, queryCode
) AS accuracy ON accuracy.measuredRunId = goldedRunQueries.runId
AND accuracy.queryCode = goldedRunQueries.queryCode
WHERE goldedRunQueries.queryCode IN ('CH001', 'CH002', 'CH003')
and goldedRunQueries.runid = 5000
ORDER BY goldedRunQueries.runId DESC, goldedRunQueries.queryCode;
Here are the two views. Both of these also get used in a standalone mode and so integrating any clauses into them is not possible.
CREATE VIEW currentGoldMarkings
AS
SELECT result.resultId, result.runId AS measuredRunId, result.documentId,
result.queryCode, result.queryValue AS measuredValue,
gold.queryValue AS goldValue,
CASE result.queryValue WHEN gold.queryValue THEN 1 ELSE 0 END AS correct
FROM results AS result
INNER JOIN gold ON gold.documentId = result.documentId
AND gold.queryCode = result.queryCode
WHERE gold.isCurrent = 1
CREATE VIEW goldedRunQueries
AS
SELECT runId, queryCode
FROM runQueries
WHERE EXISTS
( SELECT 1 AS Expr1
FROM runs
WHERE (runId = runQueries.runId)
AND (isManual = 0)
)
AND EXISTS
( SELECT 1 AS Expr1
FROM results
WHERE (runId = runQueries.runId)
AND (queryCode = runQueries.queryCode)
AND EXISTS
( SELECT 1 AS Expr1
FROM gold
WHERE (documentId = results.documentId)
AND (queryCode = results.queryCode)
)
)
Note: The above query reflects only a part of my actual query. There are 3 other left outer joins which are similar in nature to the above subquery which makes the problem far more worse.
EDIT: As suggested, here is the structure and some sample data for the tables
CREATE TABLE `results`(
`resultId` int auto_increment NOT NULL,
`runId` int NOT NULL,
`documentId` int NOT NULL,
`queryCode` char(5) NOT NULL,
`queryValue` char(1) NOT NULL,
`comment` varchar(255) NULL,
CONSTRAINT `PK_results` PRIMARY KEY
(
`resultId`
)
);
insert into results values (100, 242300, 'AC001', 'I', NULL)
insert into results values (100, 242300, 'AC001', 'S', NULL)
insert into results values (150, 242301, 'AC005', 'I', 'abc')
insert into results values (100, 242300, 'AC001', 'I', NULL)
insert into results values (109, 242301, 'PQ001', 'S', 'zzz')
insert into results values (400, 242400, 'DD006', 'I', NULL)
CREATE TABLE `gold`(
`goldId` int auto_increment NOT NULL,
`runDate` datetime NOT NULL,
`documentId` int NOT NULL,
`queryCode` char(5) NOT NULL,
`queryValue` char(1) NOT NULL,
`comment` varchar(255) NULL,
`isCurrent` tinyint(1) NOT NULL DEFAULT 0,
CONSTRAINT `PK_gold` PRIMARY KEY
(
`goldId`
)
);
insert into gold values ('2015-02-20 00:00:00', 138904, 'CH001', 'N', NULL, 1)
insert into gold values ('2015-05-20 00:00:00', 138904, 'CH001', 'N', 'aaa', 1)
insert into gold values ('2016-02-20 00:00:00', 138905, 'CH002', 'N', NULL, 0)
insert into gold values ('2015-12-12 00:00:00', 138804, 'CH001', 'N', 'zzzz', 1)
CREATE TABLE `runQueries`(
`runId` int NOT NULL,
`queryCode` char(5) NOT NULL,
CONSTRAINT `PK_runQueries` PRIMARY KEY
(
`runId`,
`queryCode`
)
);
insert into runQueries values (100, 'AC001')
insert into runQueries values (109, 'PQ001')
insert into runQueries values (400, 'DD006')
CREATE TABLE `runs`(
`runId` int auto_increment NOT NULL,
`runName` varchar(63) NOT NULL,
`isManual` tinyint(1) NOT NULL,
`runDate` datetime NOT NULL,
`comment` varchar(1023) NULL,
`folderName` varchar(63) NULL,
`documentSetId` int NOT NULL,
`pipelineVersion` varchar(50) NULL,
`isArchived` tinyint(1) NOT NULL DEFAULT 0,
`pipeline` varchar(50) NULL,
CONSTRAINT `PK_runs` PRIMARY KEY
(
`runId`
)
);
insert into runs values ('test1', 0, '2015-08-04 06:30:46.000000', 'zzzz', '2015-08-04_103046', 2, '2015-08-03', 0, NULL)
insert into runs values ('test2', 1, '2015-12-04 12:30:46.000000', 'zzzz', '2015-08-04_103046', 2, '2015-08-03', 0, NULL)
insert into runs values ('test3', 1, '2015-06-24 10:56:46.000000', 'zzzz', '2015-08-04_103046', 2, '2015-08-03', 0, NULL)
insert into runs values ('test4', 1, '2016-05-04 11:30:46.000000', 'zzzz', '2015-08-04_103046', 2, '2015-08-03', 0, NULL)
First, let's try to improve the performance via indexes:
results: INDEX(runId, queryCode) -- in either order
gold: INDEX(documentId, query_code, isCurrent) -- in that order
After that, update the CREATE TABLEs in the question and add the output of:
EXPLAIN EXTENDED SELECT ...;
SHOW WARNINGS;
What version are you running? You effectively have FROM ( SELECT ... ) JOIN ( SELECT ... ). Before 5.6, neither subquery had an index; with 5.6, an index is generated on the fly.
It is a shame that the query is built that way, since you know which one to use: and goldedRunQueries.runid = 5000.
Bottom Line: add the indexes; upgrade to 5.6 or 5.7; if that is not enough, then rethink the use of VIEWs.
I want to split rows using trigger, to 2 different tables if rows are more then 5 then insert only 5 rows to table leave and others rows to table nonpay_leave . I have a working trigger which insert rows only in one (I included trigger and my database code at the bottom of question).
currently working trigger
I have a table called staff_leave_application which have this columns :
id_staff_leave_application | staff_id_staff | leave_type_id_leave_type | start_date | end_date | joining_date
and it has a trigger called tn_air_staff_leave_application:
DELIMITER $$
USE `mydb`$$
CREATE
DEFINER=`root`#`localhost`
TRIGGER `mydb`.`tn_air_staff_leave_application`
AFTER INSERT ON `mydb`.`staff_leave_application`
FOR EACH ROW
BEGIN
SET #counter := -1;
WHILE (#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) DO
INSERT INTO `leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
END WHILE;
END$$
what above trigger actually do?
This trigger run after insert on staff_leave_application. The trigger split currently inserted row in staff_leave_application by per day per row from date range and then insert rows to the table called leave each day per row.
Then, What i want actually ???
I want to change this trigger, so that if new rows are more then 5 then insert other rows to another table called nonpay_leave. like:
if trigger generates 7 rows, then insert first 5 rows to table leave and other 2 rows to table nonpay_leave.
My database structure
--
-- Table structure for table `designation`
--
CREATE TABLE IF NOT EXISTS `designation` (
`id_designation` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id_designation`),
UNIQUE KEY `id_designation_UNIQUE` (`id_designation`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
--
-- Dumping data for table `designation`
--
INSERT INTO `designation` (`id_designation`, `name`) VALUES
(10, 'Manager'),
(12, 'Medical Officer'),
(13, 'Peon');
-- --------------------------------------------------------
--
-- Table structure for table `leave`
--
CREATE TABLE IF NOT EXISTS `leave` (
`id_leave` int(11) NOT NULL AUTO_INCREMENT,
`staff_leave_application_id_staff_leave_application` int(11) NOT NULL,
`staff_leave_application_staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`date` date NOT NULL,
`active` int(11) NOT NULL DEFAULT '1',
`date_updated` date NOT NULL,
PRIMARY KEY (`id_leave`,`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`),
KEY `fk_table1_leave_type1` (`leave_type_id_leave_type`),
KEY `fk_table1_staff_leave_application1` (`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;
--
-- Dumping data for table `leave`
--
INSERT INTO `leave` (`id_leave`, `staff_leave_application_id_staff_leave_application`, `staff_leave_application_staff_id_staff`, `leave_type_id_leave_type`, `date`, `active`, `date_updated`) VALUES
(21, 12, 7, 8, '2013-01-22', 1, '2013-01-21'),
(22, 12, 7, 8, '2013-01-23', 1, '2013-01-21'),
(23, 12, 7, 8, '2013-01-24', 1, '2013-01-21'),
(24, 12, 7, 8, '2013-01-25', 1, '2013-01-21'),
(25, 13, 7, 9, '2013-01-30', 1, '2013-01-21'),
(26, 13, 7, 9, '2013-01-31', 1, '2013-01-21'),
(27, 14, 7, 8, '2013-02-11', 1, '2013-01-21'),
(28, 14, 7, 8, '2013-02-12', 1, '2013-01-21'),
(29, 14, 7, 8, '2013-02-13', 1, '2013-01-21'),
(30, 14, 7, 8, '2013-02-14', 1, '2013-01-21'),
(31, 14, 7, 8, '2013-02-15', 1, '2013-01-21');
-- --------------------------------------------------------
--
-- Table structure for table `leave_allowed`
--
CREATE TABLE IF NOT EXISTS `leave_allowed` (
`id_leave_allowed` int(11) NOT NULL AUTO_INCREMENT,
`staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`days` float NOT NULL,
PRIMARY KEY (`id_leave_allowed`),
UNIQUE KEY `id_leave_allowed_UNIQUE` (`id_leave_allowed`),
KEY `fk_leave_allowed_staff1` (`staff_id_staff`),
KEY `fk_leave_allowed_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `leave_allowed`
--
INSERT INTO `leave_allowed` (`id_leave_allowed`, `staff_id_staff`, `leave_type_id_leave_type`, `days`) VALUES
(1, 7, 8, 2.5),
(2, 7, 9, 200);
-- --------------------------------------------------------
--
-- Table structure for table `leave_app_view`
--
CREATE ALGORITHM=UNDEFINED DEFINER=`1`#`localhost` SQL SECURITY DEFINER VIEW `mydb`.`leave_app_view` AS select `mydb`.`staff`.`name` AS `name`,`mydb`.`staff`.`file_no` AS `file_no`,`mydb`.`staff`.`photo` AS `photo`,`mydb`.`staff_leave_application`.`leave_type_id_leave_type` AS `leave_type_id_leave_type`,`mydb`.`staff_leave_application`.`start_date` AS `start_date`,`mydb`.`staff_leave_application`.`end_date` AS `end_date`,`mydb`.`staff_leave_application`.`joining_date` AS `joining_date` from (`mydb`.`staff` join `mydb`.`staff_leave_application` on((`mydb`.`staff`.`id_staff` = `mydb`.`staff_leave_application`.`staff_id_staff`)));
--
-- Dumping data for table `leave_app_view`
--
INSERT INTO `leave_app_view` (`name`, `file_no`, `photo`, `leave_type_id_leave_type`, `start_date`, `end_date`, `joining_date`) VALUES
('Rahul Ayan', '54', NULL, 8, '2013-01-22', '2013-01-25', '2013-01-26'),
('Rahul Ayan', '54', NULL, 9, '2013-01-30', '2013-01-31', '2013-02-01'),
('Rahul Ayan', '54', NULL, 8, '2013-02-11', '2013-02-15', '2013-02-16');
-- --------------------------------------------------------
--
-- Table structure for table `leave_balance`
--
CREATE TABLE IF NOT EXISTS `leave_balance` (
`id_leave_balance` int(11) NOT NULL AUTO_INCREMENT,
`staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`balance` int(3) NOT NULL,
`date_added` date NOT NULL,
PRIMARY KEY (`id_leave_balance`),
UNIQUE KEY `id_leave_balance_UNIQUE` (`id_leave_balance`),
KEY `fk_leave_balance_staff1` (`staff_id_staff`),
KEY `fk_leave_balance_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `leave_balance`
--
INSERT INTO `leave_balance` (`id_leave_balance`, `staff_id_staff`, `leave_type_id_leave_type`, `balance`, `date_added`) VALUES
(1, 7, 8, 230, '2013-01-21'),
(2, 7, 9, 200, '2013-01-21');
-- --------------------------------------------------------
--
-- Table structure for table `leave_balance_view`
--
CREATE ALGORITHM=UNDEFINED DEFINER=`1`#`localhost` SQL SECURITY DEFINER VIEW `mydb`.`leave_balance_view` AS select `mydb`.`leave_balance`.`staff_id_staff` AS `staff_id_staff`,`leave_taken`.`leave_type_id_leave_type` AS `leave_type_id_leave_type`,(`mydb`.`leave_balance`.`balance` - `leave_taken`.`days`) AS `new_balance`,`mydb`.`leave_balance`.`date_added` AS `date_added` from ((`mydb`.`staff` join `mydb`.`leave_taken` on((`mydb`.`staff`.`id_staff` = `leave_taken`.`staff_leave_application_staff_id_staff`))) join `mydb`.`leave_balance` on(((`leave_taken`.`staff_leave_application_staff_id_staff` = `mydb`.`leave_balance`.`staff_id_staff`) and (`leave_taken`.`leave_type_id_leave_type` = `mydb`.`leave_balance`.`leave_type_id_leave_type`))));
--
-- Dumping data for table `leave_balance_view`
--
INSERT INTO `leave_balance_view` (`staff_id_staff`, `leave_type_id_leave_type`, `new_balance`, `date_added`) VALUES
(7, 8, 221, '2013-01-21'),
(7, 9, 198, '2013-01-21');
-- --------------------------------------------------------
--
-- Table structure for table `leave_taken`
--
CREATE ALGORITHM=UNDEFINED DEFINER=`1`#`localhost` SQL SECURITY DEFINER VIEW `mydb`.`leave_taken` AS select `mydb`.`leave`.`staff_leave_application_staff_id_staff` AS `staff_leave_application_staff_id_staff`,`mydb`.`leave`.`leave_type_id_leave_type` AS `leave_type_id_leave_type`,count(0) AS `days` from (`mydb`.`leave` join `mydb`.`staff` on((`mydb`.`staff`.`id_staff` = `mydb`.`leave`.`staff_leave_application_staff_id_staff`))) where (`mydb`.`leave`.`active` = 1) group by `mydb`.`leave`.`leave_type_id_leave_type`;
--
-- Dumping data for table `leave_taken`
--
INSERT INTO `leave_taken` (`staff_leave_application_staff_id_staff`, `leave_type_id_leave_type`, `days`) VALUES
(7, 8, 9),
(7, 9, 2);
-- --------------------------------------------------------
--
-- Table structure for table `leave_type`
--
CREATE TABLE IF NOT EXISTS `leave_type` (
`id_leave_type` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`paid` int(11) DEFAULT NULL,
PRIMARY KEY (`id_leave_type`),
UNIQUE KEY `id_leave_type_UNIQUE` (`id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
--
-- Dumping data for table `leave_type`
--
INSERT INTO `leave_type` (`id_leave_type`, `name`, `paid`) VALUES
(8, 'Casual Leave', NULL),
(9, 'Medical Leave', NULL);
-- --------------------------------------------------------
--
-- Table structure for table `nonpay_leave`
--
CREATE TABLE IF NOT EXISTS `nonpay_leave` (
`id_nonpay_leave` int(11) NOT NULL AUTO_INCREMENT,
`staff_leave_application_id_staff_leave_application` int(11) NOT NULL,
`staff_leave_application_staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`leave_date` date DEFAULT NULL,
`active` int(1) DEFAULT NULL,
`date_updated` date DEFAULT NULL,
PRIMARY KEY (`id_nonpay_leave`,`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`),
KEY `fk_nonpay_leave_staff_leave_application1` (`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`),
KEY `fk_nonpay_leave_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `nonpay_leave`
--
-- --------------------------------------------------------
--
-- Table structure for table `staff`
--
CREATE TABLE IF NOT EXISTS `staff` (
`id_staff` int(11) NOT NULL AUTO_INCREMENT,
`file_no` varchar(45) NOT NULL,
`title_id_title` int(11) NOT NULL,
`name` varchar(80) NOT NULL,
`dob` date DEFAULT NULL,
`designation_id_designation` int(11) NOT NULL,
`status_id_status` int(11) NOT NULL,
`date_of_join` date DEFAULT NULL,
`photo` blob,
`user_name` varchar(10) DEFAULT NULL,
`password` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id_staff`),
UNIQUE KEY `id_staff_UNIQUE` (`id_staff`),
KEY `fk_staff_title` (`title_id_title`),
KEY `fk_staff_designation1` (`designation_id_designation`),
KEY `fk_staff_status1` (`status_id_status`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping data for table `staff`
--
INSERT INTO `staff` (`id_staff`, `file_no`, `title_id_title`, `name`, `dob`, `designation_id_designation`, `status_id_status`, `date_of_join`, `photo`, `user_name`, `password`) VALUES
(7, '54', 10, 'Rahul Ayan', '1991-09-14', 10, 6, '2012-01-02', NULL, NULL, NULL);
-- --------------------------------------------------------
--
-- Table structure for table `staff_leave_application`
--
CREATE TABLE IF NOT EXISTS `staff_leave_application` (
`id_staff_leave_application` int(11) NOT NULL AUTO_INCREMENT,
`staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`joining_date` date NOT NULL,
PRIMARY KEY (`id_staff_leave_application`,`staff_id_staff`),
UNIQUE KEY `id_staff_leave_UNIQUE` (`id_staff_leave_application`),
KEY `fk_staff_leave_staff1` (`staff_id_staff`),
KEY `fk_staff_leave_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
--
-- Dumping data for table `staff_leave_application`
--
INSERT INTO `staff_leave_application` (`id_staff_leave_application`, `staff_id_staff`, `leave_type_id_leave_type`, `start_date`, `end_date`, `joining_date`) VALUES
(12, 7, 8, '2013-01-22', '2013-01-25', '2013-01-26'),
(13, 7, 9, '2013-01-30', '2013-01-31', '2013-02-01'),
(14, 7, 8, '2013-02-11', '2013-02-15', '2013-02-16');
--
-- Triggers `staff_leave_application`
--
DROP TRIGGER IF EXISTS `tn_air_staff_leave_application`;
DELIMITER //
CREATE TRIGGER `tn_air_staff_leave_application` AFTER INSERT ON `staff_leave_application`
FOR EACH ROW BEGIN
SET #counter := -1;
WHILE (#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) DO
INSERT INTO `leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
END WHILE;
END
//
DELIMITER ;
-- --------------------------------------------------------
--
-- Table structure for table `status`
--
CREATE TABLE IF NOT EXISTS `status` (
`id_status` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(45) NOT NULL,
PRIMARY KEY (`id_status`),
UNIQUE KEY `id_ststus_UNIQUE` (`id_status`),
UNIQUE KEY `type_UNIQUE` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping data for table `status`
--
INSERT INTO `status` (`id_status`, `type`) VALUES
(6, 'Contract'),
(7, 'Permanent');
-- --------------------------------------------------------
--
-- Table structure for table `title`
--
CREATE TABLE IF NOT EXISTS `title` (
`id_title` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(5) NOT NULL,
PRIMARY KEY (`id_title`),
UNIQUE KEY `id_title_UNIQUE` (`id_title`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
--
-- Dumping data for table `title`
--
INSERT INTO `title` (`id_title`, `name`) VALUES
(10, 'Mr'),
(11, 'Dr'),
(12, 'Mrs'),
(13, 'Miss');
--
-- Constraints for dumped tables
--
--
-- Constraints for table `leave`
--
ALTER TABLE `leave`
ADD CONSTRAINT `fk_table1_leave_type1` FOREIGN KEY (`leave_type_id_leave_type`) REFERENCES `leave_type` (`id_leave_type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_table1_staff_leave_application1` FOREIGN KEY (`staff_leave_application_id_staff_leave_application`, `staff_leave_application_staff_id_staff`) REFERENCES `staff_leave_application` (`id_staff_leave_application`, `staff_id_staff`) ON DELETE CASCADE ON UPDATE NO ACTION;
--
-- Constraints for table `leave_allowed`
--
ALTER TABLE `leave_allowed`
ADD CONSTRAINT `fk_leave_allowed_leave_type1` FOREIGN KEY (`leave_type_id_leave_type`) REFERENCES `leave_type` (`id_leave_type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_leave_allowed_staff1` FOREIGN KEY (`staff_id_staff`) REFERENCES `staff` (`id_staff`) ON DELETE CASCADE ON UPDATE NO ACTION;
--
-- Constraints for table `leave_balance`
--
ALTER TABLE `leave_balance`
ADD CONSTRAINT `fk_leave_balance_leave_type1` FOREIGN KEY (`leave_type_id_leave_type`) REFERENCES `leave_type` (`id_leave_type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_leave_balance_staff1` FOREIGN KEY (`staff_id_staff`) REFERENCES `staff` (`id_staff`) ON UPDATE NO ACTION;
--
-- Constraints for table `nonpay_leave`
--
ALTER TABLE `nonpay_leave`
ADD CONSTRAINT `fk_nonpay_leave_staff_leave_application1` FOREIGN KEY (`staff_leave_application_id_staff_leave_application`, `staff_leave_application_staff_id_staff`) REFERENCES `staff_leave_application` (`id_staff_leave_application`, `staff_id_staff`) ON DELETE CASCADE ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_nonpay_leave_leave_type1` FOREIGN KEY (`leave_type_id_leave_type`) REFERENCES `leave_type` (`id_leave_type`) ON DELETE NO ACTION ON UPDATE NO ACTION;
--
-- Constraints for table `staff`
--
ALTER TABLE `staff`
ADD CONSTRAINT `fk_staff_designation1` FOREIGN KEY (`designation_id_designation`) REFERENCES `designation` (`id_designation`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_staff_status1` FOREIGN KEY (`status_id_status`) REFERENCES `status` (`id_status`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_staff_title` FOREIGN KEY (`title_id_title`) REFERENCES `title` (`id_title`) ON DELETE NO ACTION ON UPDATE NO ACTION;
--
-- Constraints for table `staff_leave_application`
--
ALTER TABLE `staff_leave_application`
ADD CONSTRAINT `fk_staff_leave_leave_type1` FOREIGN KEY (`leave_type_id_leave_type`) REFERENCES `leave_type` (`id_leave_type`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_staff_leave_staff1` FOREIGN KEY (`staff_id_staff`) REFERENCES `staff` (`id_staff`) ON DELETE CASCADE ON UPDATE NO ACTION;
Updated Trigger
BEGIN
set #loopcounter := 0;
set #counter:= -1;
set #balance:= (SELECT new_balance FROM leave_balance_view WHERE staff_id_staff = new.staff_id_staff and leave_type_id_leave_type = new.leave_type_id_leave_type);
-- set #newrows:= (select count(*) from tn_air_staff_leave_application);
WHILE ((#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) && (#loopcounter < #balance)) DO
INSERT INTO `leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
set #loopcounter := #loopcounter + 1;
END WHILE;
set #counter:=+(#balance - 1);
set #loopcounter:=0;
WHILE ((#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) && (#loopcounter < 2)) DO
INSERT INTO `nonpay_leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
end while;
END$$
set #loopcounter := 0;
set #counter:= -1;
WHILE ((#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) && (#loopcounter <5)) DO
INSERT INTO `leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
set #loopcounter := #loopcounter + 1;
END WHILE;
set #counter:=+4 (basically adjusting for the previous 5 that u marked in)
set #loopcounter:=0;
WHILE ((#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) && (#loopcounter <2)) DO
insert into NO_PAY_LEAVE
* the idea is a new loop_counter which goes to 5 before it breaks out of first loop.
* a new 2nd loop_counter which breaks at 2 or more (not sure wht the requirement is, maybe u wont need it in the 2nd loop)
* ur original counter adjusted to either +4 in the 2nd loop (not sure which one, sorta confused but i think it shud be +4 or it cud be
-6)
Ok i have edited and think this is what the new logic shud b.. many counters have changed
well alrite i get u, now u will have to do what u said.. before u enter any loop.. loop1 (max times it can execute is #balance times).. loop2 (it shud compulsarily execute the remainder times).. i think u shud set a new counter called leave_counter in the beginning itself which will determine how many times the Leave Loop will execute..
BEGIN
set #loopcounter := 0;
set #counter:= -1;
set #balance:= (SELECT new_balance FROM leave_balance_view WHERE staff_id_staff = new.staff_id_staff and leave_type_id_leave_type = new.leave_type_id_leave_type);
set #leavecounter:=+(#balance - 1);
-- set #newrows:= (select count(*) from tn_air_staff_leave_application);
WHILE ((#counter < DATEDIFF(DATE(new.end_date), DATE(new.start_date))) && (#loopcounter < #balance) && (#balance>0)) DO
INSERT INTO `leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #counter:=#counter + 1 DAY), 1, CURDATE());
set #loopcounter := #loopcounter + 1;
set #balance := #balance - 1;
END WHILE;
WHILE ((#leavecounter < DATEDIFF(DATE(new.end_date), DATE(new.start_date)))) DO
INSERT INTO `nonpay_leave`(staff_leave_application_id_staff_leave_application, staff_leave_application_staff_id_staff, leave_type_id_leave_type, date, active, date_updated)
VALUES (new.id_staff_leave_application, new.staff_id_staff, new.leave_type_id_leave_type, DATE_ADD(new.start_date, INTERVAL #leavecounter:=#leavecounter + 1 DAY), 1, CURDATE());
end while;
END$$
BOTTOMLINE::::::
i have edited ur sql command by introducing a new counter called leave_counter which will determine how many times ur leave_loop shud run.. also in the first loop i have made sure that it does not execute more than #balance times by introducing the #balance in the first loop.. u can see the edited reply.. Loop 1: Executes max (#balance) times... Loop 2: Executes (no of days leave taken) - (#balance) times ...