Reputation: 67
I have the following table named foo:
ID | D1 | D2 | D3 |
---------------------
1 | 47 | 3 | 71 |
2 | 47 | 98 | 82 |
3 | 0 | 99 | 3 |
4 | 3 | 100 | 6 |
5 | 48 | 10 | 3 |
6 | 49 | 12 | 4 |
I want to run a select query and have the results show like this
ID | D1 | D2 | D3 | Result |
------------------------------
1 | 47 | 3 | 71 | D3 |
2 | 47 | 98 | 82 | D2 |
3 | 0 | 99 | 3 | D2 |
4 | 3 | 100 | 6 | D2 |
5 | 48 | 10 | 3 | D1 |
6 | 49 | 12 | 4 | D1 |
So, basically I want to get Maximum value between D1, D2, D3 column divided by id. As You may seen , ID 1 have D3 in the Result column since Maximum value between D1 : D2 : D3
That Means 4 : 3 : 71 , Max value is 71. Thats Why The Result show 'D3'
Is there a way to do this in a sql query ?
Thanks!
Upvotes: 0
Views: 98
Reputation: 33935
Consider the following - a normalized approach...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL
,d INT NOT NULL
,val INT NOT NULL
,PRIMARY KEY(id,d)
);
INSERT INTO my_table VALUES
(1,1,47),
(2,1,47),
(3,1,0),
(4,1,3),
(5,1,48),
(6,1,49),
(1,2,3),
(2,2,98),
(3,2,99),
(4,2,100),
(5,2,10),
(6,2,12),
(1,3,71),
(2,3,82),
(3,3,3),
(4,3,6),
(5,3,3),
(6,3,4);
SELECT * FROM my_table;
+----+---+-----+
| id | d | val |
+----+---+-----+
| 1 | 1 | 47 |
| 1 | 2 | 3 |
| 1 | 3 | 71 |
| 2 | 1 | 47 |
| 2 | 2 | 98 |
| 2 | 3 | 82 |
| 3 | 1 | 0 |
| 3 | 2 | 99 |
| 3 | 3 | 3 |
| 4 | 1 | 3 |
| 4 | 2 | 100 |
| 4 | 3 | 6 |
| 5 | 1 | 48 |
| 5 | 2 | 10 |
| 5 | 3 | 3 |
| 6 | 1 | 49 |
| 6 | 2 | 12 |
| 6 | 3 | 4 |
+----+---+-----+
SELECT x.*
FROM my_table x
JOIN
( SELECT id,MAX(val) max_val FROM my_table GROUP BY id) y
ON y.id = x.id
AND y.max_val = x.val;
+----+---+-----+
| id | d | val |
+----+---+-----+
| 1 | 3 | 71 |
| 2 | 2 | 98 |
| 3 | 2 | 99 |
| 4 | 2 | 100 |
| 5 | 1 | 48 |
| 6 | 1 | 49 |
+----+---+-----+
(This is intended as a MySQL solution - I'm not familiar with ORACLE syntax, so apologies if this doesn't port)
Does this answer your comment?
SELECT x.* , y.max_val
FROM my_table x
JOIN
( SELECT id,MAX(val) max_val FROM my_table GROUP BY id) y
ON y.id = x.id ;
+----+---+-----+---------+
| id | d | val | max_val |
+----+---+-----+---------+
| 1 | 1 | 47 | 71 |
| 1 | 2 | 3 | 71 |
| 1 | 3 | 71 | 71 |
| 2 | 1 | 47 | 98 |
| 2 | 2 | 98 | 98 |
| 2 | 3 | 82 | 98 |
| 3 | 1 | 0 | 99 |
| 3 | 2 | 99 | 99 |
| 3 | 3 | 3 | 99 |
| 4 | 1 | 3 | 100 |
| 4 | 2 | 100 | 100 |
| 4 | 3 | 6 | 100 |
| 5 | 1 | 48 | 48 |
| 5 | 2 | 10 | 48 |
| 5 | 3 | 3 | 48 |
| 6 | 1 | 49 | 49 |
| 6 | 2 | 12 | 49 |
| 6 | 3 | 4 | 49 |
+----+---+-----+---------+
Upvotes: 0
Reputation:
For Oracle please try this one
select foo.*, case when greatest(d1, d2, d3) = d1 then 'D1'
when greatest(d1, d2, d3) = d2 then 'D2'
when greatest(d1, d2, d3) = d3 then 'D3'
end result
from foo
Upvotes: 3