2010-02-09 4 views
0

У меня проблема: моя таблица достаточно большая (миллионы строк данных), это временные данные, которые я обрабатываю. Мне нужно выбрать max и min одного столбца, присоединяющегося к некоторым критериям, обработать эту информацию и удалить данные в соответствии с теми же критериями. На самом деле, самая простая реализация выглядит следующим образом:удаление и возврат данных в PostgreSQL

select max(col), min(col) from _TABLE_ where _CONDITION_; 
... 
delete from _TABLE_ where _CONDITION_; 

стол большой, и когда я его обработать, quering, что путь в цикле, это занимает некоторое время. Я думал, что я могу оптимизировать его с помощью «возвращения» в удалении, как

delete from _TABLE_ where _CONDITION_ returning max(col), min(col); 

было бы совсем то, что мне нужно, но ... это не работает вообще :) говорить, что я не могу использовать агрегатные функции в возвращаемой статье ...

есть ли хороший способ улучшить два запроса (выбор максимального/минимального количества данных и удаление тех же данных), вместо этого сделав один запрос? Любой трюк?

спасибо заранее за любую информацию, Maxym

+0

Являются _CONDITIONS_ взаимоисключающими и относительно низкой номер? – cope360

+0

извините, что вы имеете в виду? Фактически «col» .. hm, в действительности у меня есть две колонки, которые представляют координату точки (широта и долгота), поэтому я выбираю удаление всех точек из таблицы в соответствии с некоторым прямоугольником, но я должен знать, что было min/max долгота и долгота удаленных точек (реальный, потому что примерно я мог взять прямоугольник :) – Maxym

ответ

1

Используйте функцию как это:

create temporary table test (value int); 
insert into test select generate_series(1,100); 

create or replace function delete_even_from_test_and_return_min_deleted() 
    returns int as 
$$ 
declare 
    _value record; 
    min int; 
begin 
    min=X'7FFFFFFF'; -- INT_MAX 
    for _value in 
    delete from test where value%2=0 returning value 
    loop 
    if min>_value.value then 
     min=_value.value; 
    end if; 
    end loop; 
    return min; 
end; 
$$ language plpgsql; 

select count(*) from test; 
100 

select delete_even_from_test_and_return_min_deleted(); 
2 

select count(*) from test; 
50 
+0

спасибо, я постараюсь на Mon – Maxym

7

Вы можете сделать:

with foo as(delete from table where _CONDITION_ returning col) 
select max(col), min(col) from foo 
+1

почему только с 9.1? идея заключается в использовании функции CTE, правильно? он был включен, например, в 8.4. – Maxym

+0

Да, вы правы. Я думаю, вы не можете сделать WITH (...) DELETE/INSERT до 9.1: http://www.postgresql.org/docs/9.1/static/queries-with.html. Я просто перепутал вещи, спасибо! –

Смежные вопросы