Cleaned Compressed Exercises
Cleaned Compressed Exercises
1 . Wri te af unction
GetTotalBonus(emp_id INT)
For ever y e mplo ye e with zero ' Abs ent' or ' Late' in the pr evious mon th, add a $500 b onus.
3 . Wri te a trigg er
trg_late_penalty
For emp lo yees w ith mor e than 5 absen ce s in the current mont h, delete their bonus es w ith reasons
mention ing "at tenda nce".
5 . Wri te af unction
CountAbsences(emp INT, month INT, year INT)
7 . Wri te a trigg er
trg_bonus_update
Before inserting into
Bonuses
, check if a bonus f or the sa me e mp lo yee and r eason exists for the
same month ;if yes, prevent dupl icat e bo nus insertion.
8.
Wri te a pro cedurew i th cur
so r
ListEmployeesWithNoBonuses()
Print or s elec tall e mplo ye es w ho have no treceiv ed an y bonus es in the l ast 6 month s.
Functi o n:
GetTotalBonus(emp_id INT)
sql
DELIMITER
//
CREATE
FUNCTION
GetTotalBonus(emp_id
INT
)
RETURNS
DECIMAL
(
10
,
2
)
DETERMINISTIC
BEGIN
DECLARE
total_bonus
DECIMAL
(
10
,
2
);
SELECT
IFNULL(
SUM
(
bonus_amount),
0
)
INTO
total_bonus
FROM
Bonuses
WHERE
emp_id
=
emp_id;
RETURN
total_bonus;
END
//
DELIMITER ;
For ever y e mplo ye e with zero ' Abs ent' or ' Late' in the
pr eviou sm onth
, add a
$500 bonus.
sql
DELIMITER
//
CREATE
PROCEDURE
GivePerfectAttendanceBonus()
BEGIN
DECLARE
prev_month_start
DATE
;
DECLARE
prev_month_end
DATE
;
SET
prev_month_start
=
DATE_FORMAT(
CURRENT_DATE
INTERVAL
MONTH
,
'%Y
-
%m
-
01'
);
SET
prev_month_end
=
LAST_DAY(prev_month_start);
INSERT
INTO
SELECT
e.emp_id,
500
,
'Perfect attendance bonus'
,
CURRENT_DATE
FROM
Employees e
WHERE
NOT
EXISTS
SELECT
FROM
Attend
ance a
WHERE
a.emp_id
=
e.emp_id
AND
a.date
BETWEEN
prev_month_start
AND
prev_month_end
AND
a.status
IN
(
'Absent'
,
'Late'
)
);
END
//
DELIMITER ;
3 . Tri gg er:
trg_late_penalty
is 'Late', insert a
-
$50 penalt y bonus for that
e mplo yee.
sql
DELIMITER
//
CREATE
TRIGGER
trg_late_penalty
AFTER
INSERT
ON
Attendance
FOR
EACH
ROW
BEGIN
IF NEW.status
=
'Late'
THEN
INSERT
INTO
VALUES
(NEW.emp_id,
-
50
,
'Late penalty'
, NEW.date);
END
IF;
END
//
DELIMITER ;
For emp lo yees w ith mor e than 5 absen ce s in the current mont h, delete their bonus es w ith reason
s
mention ing "at tenda nce".
sql
DELIMITER
//
CREATE
PROCEDURE
RemoveBonusesForPoorAttendance()
BEGIN
DECLARE
done
INT
DEFAULT
FALSE
;
DECLARE
v_emp_id
INT
;
DECLARE
cur
CURSOR
FOR
SELECT
emp_id
FROM
Attendance
WHERE
status
=
'Absent'
AND
YEAR
(
date
)
=
YEAR
(
CURRENT_DATE
)
AND
MONTH
(
date
)
=
MONTH
(
CURRENT_DATE
)
GROUP
BY
emp_id
HAVING
COUNT
(
*
)
>
5
;
DECLARE
CONTINUE HANDLER
FOR
NOT
FOUND
SET
done
=
TRUE
;
OPEN
cur;
read_loop: LOOP
FETCH
cur
INTO
v_emp_id;
IF done
THEN
LEAVE read_loop;
END
IF;
DELETE
FROM
Bonuses
WHERE
emp_id
=
v_emp_id
AND
reason
LIKE
'%attendance%'
;
END
LOOP;
CLOSE
cur;
END
//
DELIMITER ;
5 . Functi o n:
CountAbsences(emp INT, month INT, year INT)
sql
DELIMITER
//
CREATE
FUNCTION
CountAbsences(emp
INT
,
month
INT
,
year
INT
)
RETURNS
INT
DETERMINISTIC
BEGIN
DECLARE
absences
INT
;
SELECT
COUNT
(
*
)
INTO
absences
FROM
Attendance
WHERE
emp_id
=
emp
AND
status
=
'Absent'
AND
MONTH
(
date
)
=
month
AND
YEAR
(
date
)
=
year
;
RETURN
absences;
END
//
DELIMITER ;
For emp lo yees w ith f ewer than 3 la te da ys last month, add a $2 00 bonus labeled ' Good
punctual it y' .
sql
DELIMITER
//
CREATE
PROCEDURE
AddBonusForLateReduction()
BEGIN
DECLARE
prev_month_start
DATE
;
DECLARE
prev_month_end
DATE
;
SET
prev_month_start
=
DATE_FORMAT(
CURRENT_DATE
INTERVAL
MONTH
,
'%Y
-
%m
-
01'
);
SET
prev_month_end
=
LAST_DAY(prev_month_start);
INSERT
INTO
SELECT
e.emp_id,
200
,
'Good punctuality'
,
CURRENT_DATE
FROM
Employees e
LEFT
JOIN
SELECT
emp_id,
COUNT
(
*
)
AS
late_count
FROM
Attendance
WHERE
status
=
'Late'
AND
date
BETWEEN
prev_month_start
AND
prev_month_end
GROUP
BY
emp_id
)a
ON
e.emp_id
=
a.emp_id
WHERE
IFNULL(a.late_count,
0
)
<
3
;
END
//
DELIMITER ;
7 . Tri gg er:
trg_bonus_update
Before inserting into Bonuses, check if a b onus f or the sa me e mp lo yee and r eason exists for
the
same month ;if yes, prevent dupl icat e bo nus insertion.
sql
DELIMITER
//
CREATE
TRIGGER
trg_bonus_update
BEFORE
INSERT
ON
Bonuses
FOR
EACH
ROW
BEGIN
IF
EXISTS
(
SELECT
FROM
Bonuses
WHERE
emp_id
=
NEW.emp_id
AND
reason
=
NEW.reason
AND
YEAR
(bonus_date)
=
YEAR
(NEW.bonus_date)
AND
MONTH
(bonus_date)
=
MONTH
(NEW.bonus_date)
)
THEN
SIGNAL
SQLSTATE
'45000'
SET
MESSAGE_TEXT
=
'Duplicate bonus for
employee and reason in this month'
;
END
IF;
END
//
DELIMITER ;
Print or s elec tall e mplo ye es w ho have no treceiv ed an y bonus es in the l ast 6 month s.
sql
DELIMITER
//
CREATE
PROCEDURE
ListEmployeesWithNoBonuses()
BEGIN
DECLARE
six_months_ago
DATE
;
SET
six_months_ago
=
DATE_SUB(
CURRENT_DATE
,
INTERVAL
MONTH
);
SELECT
e.
*
FROM
Employees e
LEFT
JOIN
Bonuses b
ON
e.emp_id
=
b.emp_id
AND
b.bonus_date
>=
six_months_ago
WHERE
b.bonus_id
IS
NULL
;
END
//
DELIMITER ;
1 0 . Functio n:
CalculateNetSalary(emp INT)
sql
DELIMITER
//
CREATE
FUNCTION
CalculateNetSalary(emp
INT
)
RETURNS
DECIMAL
(
10
,
2
)
DETERMINISTIC
BEGIN
DECLARE
base_sal
DECIMAL
(
10
,
2
);
DECLARE
total_bonus
DECIMAL
(
10
,
2
);
SELECT
base_salary
INTO
base_sal
FROM
Employees
WHERE
emp_id
=
emp;
SELECT
IFNULL(
SUM
(bonus_amount),
0
)
INTO
total_bonus
FROM
Bonuses
WHERE
emp_id
=
emp;
RETURN
base_sal
+
total_bonus;
END
//
DELIMITER ;