SQL - Как выбрать уникальное поле с другим полем, связанным с минимальным значением - PullRequest
0 голосов
/ 13 апреля 2011

Существует таблица с тремя атрибутами:

TableA:
     -- Attribute1
     -- Attribute2
     -- Attribute3

Теперь я хочу получить все три атрибута, с отличным Атрибутом2, который имеет минимальное значение Атрибута3

Вот оператор SQL, который я могу придумать:

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

Пример таблицы данных выглядит следующим образом:

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

Вот ожидаемый результат:

Attribute1  Attribute2  Attribute3
att1_001    att2_001    1
att1_004    att2_002    10

Я уверен, что это не оптимизированный вариант, и я ищу его:)

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 13 апреля 2011

В PostgreSQL я бы сделал это.

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

Невозможно сказать, является ли это оптимальным. Сравните планы запросов (EXPLAIN ANALYZE select-statement) обоих операторов на вашем сервере.

0 голосов
/ 13 апреля 2011

Как насчет использования оконной функции для ранжирования строк:

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)

Обратите внимание, что какой бы подход вы ни использовали, вам нужно учитывать, какие результаты вы хотите получить, когда есть связь.Этот подход будет выбирать произвольно между связанными рядами - ваш расширит результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...