Reputation: 31
There is a table that has three attributes:
TableA:
-- Attribute1
-- Attribute2
-- Attribute3
Now I want to get all three attributes out, with distinct Attribute2 that has the minimum value of Attribute3
Here is the SQL statement that I can come up with:
select TableA.Attribute1, TableA.Attribute2, TableA.Attribute3
from TableA,
(select Attribute2, min(Attribute3) as minAttribute3
from TableA
group by Attribute2) as TableB
where TableA.Attribute2 = TableB.Attribute2
and TableA.Attribute3= TableB.minAttribute3
Example table data is as follows:
Attribute1 Attribute2 Attribute3
att1_001 att2_001 1
att1_002 att2_001 2
att1_003 att2_001 3
att1_004 att2_002 10
att1_005 att2_002 11
Here is the expected output result:
Attribute1 Attribute2 Attribute3
att1_001 att2_001 1
att1_004 att2_002 10
I am sure this is not an optimized one and am looking for one:)
Thank you in advance
Upvotes: 0
Views: 321
Reputation:
How about using a windowing function to rank the rows:
create view v as
select * from (values ('att1_001', 'att2_001', 1),
('att1_002', 'att2_001', 2),
('att1_003', 'att2_001', 3),
('att1_004', 'att2_002', 10),
('att1_005', 'att2_002', 11)) as foo(a1, a2, a3);
select * from v;
a1 | a2 | a3
----------+----------+----
att1_001 | att2_001 | 1
att1_002 | att2_001 | 2
att1_003 | att2_001 | 3
att1_004 | att2_002 | 10
att1_005 | att2_002 | 11
(5 rows)
select a1, a2, a3
from ( select a1, a2, a3, row_number() over (partition by a2 order by a3) as ord
from v ) z
where ord=1;
a1 | a2 | a3
----------+----------+----
att1_001 | att2_001 | 1
att1_004 | att2_002 | 10
(2 rows)
Note that whatever approach you use, you need to consider what results you want when there is a tie. This approach will choose in an arbitrary way between tied rows - yours will expand the results.
Upvotes: 0
Reputation: 95582
In PostgreSQL I'd do this.
select TableA.Attribute1, TableA.Attribute2, TableA.Attribute3
from TableA
inner join (select Attribute2, min(Attribute3) as minAttribute3
from TableA
group by Attribute2) t
on TableA.Attribute2 = t.Attribute2
and TableA.Attribute3 = t.minAttribute3
att1_001 att2_001 1
att1_004 att2_002 10
Whether this is optimal is impossible to say. Compare the query plans (EXPLAIN ANALYZE select-statement
) of both statements on your server.
Upvotes: 1