Question

I got this question in an exam, the teacher asked us to raise the employers' salaries using the following rules using a cursor:

  • An extra 4% for the first quarter with the highest salary.
  • An extra 6% for the second quarter with the highest salary.
  • For the rest an extra 8%

How to approach solving this.

My attempt was SELECT SALARY FROM (SELECT * FROM EMP ORDER BY SALARY) rownum > count(*)/4 to get the salary at first then add the %4 raise and update it to the new value.

I haven't tested it but I guess it might work, but I think it's a bit too far fetched and there may be a better or more efficient solution, your thought guys ?

Was it helpful?

Solution

To solve your issue, I did the following:

Create table and data:

CREATE TABLE salesperson (id INTEGER, salary INTEGER);

INSERT INTO salesperson VALUES (1, 100000);
INSERT INTO salesperson VALUES (2,  80000);
INSERT INTO salesperson VALUES (3,  60000);
INSERT INTO salesperson VALUES (4,  50000);
INSERT INTO salesperson VALUES (5,  30000);
INSERT INTO salesperson VALUES (6,  25000);
INSERT INTO salesperson VALUES (7,  12000);
INSERT INTO salesperson VALUES (8,  10000);

Then run this query (SQLFiddle here):

WITH cte AS
(
  SELECT id, salary, NTILE(4) OVER (ORDER BY salary) AS quartile
  FROM salesperson
)   --     <<== you can do a SELECT * FROM cte to see what's happening!
SELECT
       id,
       salary,
       CASE quartile
         WHEN 1 THEN salary * 1.08
         WHEN 2 THEN salary * 1.08
         WHEN 3 THEN salary * 1.06 
         WHEN 4 THEN salary * 1.04
       END as new_salary
FROM cte;

Result:

ID  SALARY  NEW_SALARY
1   100000  104000
2   80000   83200
3   60000   63600
4   50000   53000
5   30000   32400
6   25000   27000
7   12000   12960
8   10000   10800 

HTH and welcome to the forum! :-)

You can read the Oracle NTILE documentation here and an explanation from the excellent oracle-base site here.

EDIT:

You can also do it in one pass - but I think the cte (COMMON TABLE EXPRESSION - or WITH clause) shows the thought process more clearly. Thus:

SELECT
       id,
       salary,
       CASE NTILE(4) OVER (ORDER BY salary) 
         WHEN 1 THEN salary * 1.08
         WHEN 2 THEN salary * 1.08
         WHEN 3 THEN salary * 1.06 
         WHEN 4 THEN salary * 1.04
       END as new_salary
FROM salesperson
ORDER BY id;

Same result (fiddle)!

OTHER TIPS

I meant the idea, not the literal implementation of the query

I'll write the idea too, well?

WITH cte AS ( SELECT *, RANK(salary) OVER (PARTITION BY quarter ORDER BY salary DESC) rnk 
              FROM datatable )
UPDATE datatable
SET salary = salary * CASE WHEN rnk=1 AND quarter=1 THEN 1.04
                           WHEN rnk=1 AND quarter=2 THEN 1.06
                                                    ELSE 1.08 END
FROM cte
WHERE id = cte.id
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top