2010-02-09 4 views
0

J'ai le problème suivant: ma table est assez grosse (millions de lignes de données), ce sont des données temporaires que je traite. J'ai besoin de sélectionner max et min d'une colonne en fonction de certains critères, traiter cette information et supprimer des données selon les mêmes critères. En fait, la mise en œuvre semble simple comme:supprimer et retourner des données dans PostgreSQL

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

est grande, et quand je le traiter, quering cette façon dans le cycle, il faut un certain temps. Je pensais que je peux optimiser en utilisant le « retour » à supprimer, comme

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

il serait tout à fait ce que je dois, mais ... ça ne fonctionne pas du tout :) parler que je ne peux pas utiliser des fonctions d'agrégation dans la clause de retour ...

Y a-t-il un bon moyen d'améliorer deux requêtes (en sélectionnant max/min de données et en supprimant les mêmes données) en faisant une requête à la place? Un truc?

vous remercie d'avance pour toute information, Maxym

+0

sont la _CONDITIONS_ mutuellement exclusives et relativement faible nombre? – cope360

+0

désolé, que voulez-vous dire? En fait "col" .. hm, en réalité j'ai deux colonnes, qui représentent la coordonnée du point (latitude et longitude), donc je sélectionne supprimer tous les points de la table selon un rectangle, mais je dois savoir quel était le min/max longitude et la longitude des points supprimés (réel, parce que je pourrais prendre environ rectangle :) – Maxym

Répondre

1

Utiliser une fonction comme ceci:

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

merci, je vais essayer Mon – Maxym

7

Vous pouvez faire:

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

pourquoi seulement à partir de 9.1? l'idée est d'utiliser la fonction CTE, non? il a été activé par exemple dans 8.4 aussi. – Maxym

+0

oui, vous avez raison. Je pense que vous ne pouvez pas faire avec (...) DELETE/INSERT avant 9.1: http://www.postgresql.org/docs/9.1/static/queries-with.html. J'ai juste mélangé les choses, merci! –

Questions connexes