mysql trigger - update value, value= row count - mysql

I want to run a mysql trigger to update value of table leave_taken col num, when a table called leave was updated, inserted or deleted.
Like if I insert this rows to 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
(7, 7, 6, 7, '2013-01-21', 1, '2013-01-18'),
(8, 7, 6, 7, '2013-01-22', 1, '2013-01-18'),
(9, 7, 6, 7, '2013-01-23', 1, '2013-01-18'),
(10, 7, 6, 7, '2013-01-24', 1, '2013-01-18'),
(11, 7, 6, 7, '2013-01-25', 2, '2013-01-18');
then table leave_taken col num value was updated to 5 where:
staff_leave_application_staff_id_staff = currently updated staff_leave_application_staff_id_staff,
and
leave_type_id_leave_type = currently updated leave_type_id_leave_type
I have included the Table below.
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=12 ;
Table Leave taken:
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=1 ;

First, define a unique key over the identifying columns in your leave table:
ALTER TABLE leave
ADD UNIQUE (staff_leave_application_staff_id_staff, leave_type_id_leave_type);
Then go ahead and define your triggers:
CREATE TRIGGER my_insert_trigger AFTER INSERT ON leave FOR EACH ROW
INSERT INTO leave_taken
(staff_leave_application_staff_id_staff, leave_type_id_leave_type, num)
VALUES
(NEW.staff_leave_application_staff_id_staff, NEW.leave_type_id_leave_type, 1)
ON DUPLICATE KEY UPDATE
num = num + 1;
CREATE TRIGGER my_delete_trigger AFTER DELETE ON leave FOR EACH ROW
UPDATE leave_taken
SET num = num - 1
WHERE staff_leave_application_staff_id_staff = OLD.staff_leave_application_staff_id_staff
AND leave_type_id_leave_type = OLD.leave_type_id_leave_type;
DELIMITER ;;
CREATE TRIGGER my_update_trigger AFTER UPDATE ON leave FOR EACH ROW
IF NOT (
NEW.staff_leave_application_staff_id_staff <=> OLD.staff_leave_application_staff_id_staff
AND NEW.leave_type_id_leave_type <=> OLD.leave_type_id_leave_type
) THEN
UPDATE leave_taken
SET num = num - 1
WHERE staff_leave_application_staff_id_staff = OLD.staff_leave_application_staff_id_staff
AND leave_type_id_leave_type = OLD.leave_type_id_leave_type;
INSERT INTO leave_taken
(staff_leave_application_staff_id_staff, leave_type_id_leave_type, num)
VALUES
(NEW.staff_leave_application_staff_id_staff, NEW.leave_type_id_leave_type, 1)
ON DUPLICATE KEY UPDATE
num = num + 1;
END IF;;
DELIMITER ;

Related

adding foreign key from other table based on column values of first table - MySql

I am new to mysql
I have two Tables in my database.
id_details_table
CREATE TABLE `id_details_table` (
`ID` int(11) NOT NULL,
`CNIC` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
sample record
INSERT INTO `id_details_table` (`ID`, `CNIC`) VALUES
(1, '3230328119795'),
(2, '4200004873681'),
(3, '4230188867895'),
(4, '3740566124323'),
(5, '4220191179125');
mobiles_sim_details
> CREATE TABLE `mobiles_sim_details` (
`Mobile` double DEFAULT NULL,
> `CNIC` varchar(255) DEFAULT NULL, `id_cnic` int(11) DEFAULT NULL )
> ENGINE=InnoDB DEFAULT CHARSET=latin1;
sample Record for table
INSERT INTO `mobiles_sim_details` (`Mobile`, `CNIC`, `id_cnic`) VALUES
(3000651082, '3230328119795', 0),
(3040877459, '4200004873681', 0),
(3013329415, '4230188867895', 0),
(3028590340, '3740566124323', 0),
(3000720166, '4220191179125', 0);
2 columns CNIC are present in both tables
Now What I want is, where there is 0 in the 2nd table I want it to be auto filled with the relevant ID from table 1 based on the data of CNIC from 2nd table.
I have tried this query but it didn't worked
UPDATE `mobiles_sim_details` SET `id_cnic`='[value-3]' WHERE (SELECT id FROM id_details_table WHERE CNIC = mobiles_sim_details.CNIC);
How can i Acheive this ?
UPDATE mobiles_sim_details t1
JOIN id_details_table t2 USING (CNIC)
SET t1.id_cnic = t2.id

Complicated query to get opening balance, added_qty, reduced_qty and ending balance for a specific period

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 !

select value from another table - mysql

I have 2 tables "srot_data" and "vada"
CREATE TABLE `vada`
(
`id` INT(10) NOT NULL,
`cislo` INT(10) DEFAULT NULL,
`popis` VARCHAR(50) DEFAULT NULL
)
engine=innodb
DEFAULT charset=utf8;
CREATE TABLE `srot_data`
(
`id` INT(10) NOT NULL,
`vada` INT(10) DEFAULT NULL
);
INSERT INTO `srot_data` (`ID`, `Datum`, `ID_obsluha`, `Linka`, `Kontejner`, `Vada`, `m_srot`, `m_pres`, `blok`) VALUES (1, '2018-04-16 11:23:44', 21, 'EXMET2', 'ELDY-', 18, '27.500', '12.500', 1),(2, '2018-04-16 12:18:06', 21, 'EXMET2', 'ELDY-', 5, '1.000', '0.000', NULL);
INSERT INTO `vada` (`ID`, `Cislo`, `Popis`) VALUES(1, 1, 'Najíždění výroby(resp. nové elektrody)'),(2, 2, 'Expander - poškozená mřížka'),(3, 3, 'Olověný pás - koroze '),(4, 4, 'Olověný pás - potrhaná mřížka'),(5, 5, 'Pastovačka - nedopastované elektrody');
Vada from srot_data = ID from vada. And I need to get Popis from table vada.
My sql is:
$sql = "SELECT count(blok) AS Total ,
Vada AS vada
FROM srot_data
LEFT JOIN vada ON vada.Popis = srot_data.Vada
WHERE Linka = 'EXMET1'
GROUP BY vada
ORDER BY Total DESC limit 1";
but it doesn´t work. I'm getting a number (vada from table srot_data). But not getting a text value from Popis (from table vada).
{"Total":"37", "vada":"5".}
And I need
{"Total":"37", "vada":"Pastovačka - nedopastované elektrody".}
Linka and blok are not important for this problem, so I deleted it from tabel for this time.

specify conditions from outer query on a materialized subquery

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.

mysql trigger insert in multiple table by condition

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 ...