I have an employee table that looks like this:
| id | name | q1 | q2 | q3 | q4 | +----+------+----+----+----+----+ | 1 | John | 20 | 30 | 10 | 4 | | 2 | Ram | 07 | 10 | 03 | 4 | | 3 | John | 05 | 03 | 15 | 40 | | 4 | Sree | 12 | 05 | 20 | 25 |
I needed to get the minimum value and maximum value of questions where the id is equal to 4. In this case, I needed 5 and 25 returned. I acheived that using the following query:
SELECT id, name, LEAST(q1, q2, q3, q4) AS minValue, GREATEST(q1, q2, q3, q4) AS maxValue FROM employee WHERE id = 4;
But what this doesn’t return is the question id. How can I adjust my query to show that q2 is the minimum and q4 is the maximum? I know I could write a big case statement, but I also feel like it could be accomplished using a join but I can’t figure it out.
Note: This is for a postgresql database, but I tagged MySQL as well because I know it also supports the LEAST
and GREATEST
functions. If the solution is very different for both, then I will remove this note and make a separate question.
EDIT
I have an SQL Fiddle already.
Advertisement
Answer
You can use a case
statement:
CASE WHEN LEAST(q1, q2, q3, q4) = q1 THEN 'q1' WHEN LEAST(q1, q2, q3, q4) = q2 THEN 'q2' WHEN LEAST(q1, q2, q3, q4) = q3 THEN 'q3' ELSE 'q4' END as minQuestion
(Note: it will lose information over ties.)
If you’re interested in ties, approaching it with a subquery and arrays will do the trick:
with employee as ( select id, q1, q2, q3, q4 from (values (1, 1, 1, 3, 4), (2, 4, 3, 1, 1) ) as rows (id, q1, q2, q3, q4) ) SELECT least(q1, q2, q3, q4), array( select q from (values (q1, 'q1'), (q2, 'q2'), (q3, 'q3'), (q4, 'q4') ) as rows (v, q) where v = least(q1, q2, q3, q4) ) as minQuestions FROM employee e WHERE e.id = 1;