PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Re : Général » Erreur Insert utilisant des vues » 26/12/2016 19:05:40

OK, au temps pour moi.
L'erreur venait de la fonction fct_return_or_create_id_mod qui attend en fait un paramètre supplémentaire.
Et Marc Cousin avait raison, la règle était du coup inexistante.
Merci pour l'aide.

#2 Re : Général » Erreur Insert utilisant des vues » 26/12/2016 18:20:08

Oui oui, la règle est bien créée. Petit détail, la règle d'insertion en exemple, et recopiées ci après, implique l'écriture simultanée dans la table t_plot, mais également dans les tables t_block et t_mod si mon block et mon mod n'existent pas encore (utilisation des fonctions fct_return_or_create_id_block, fct_return_or_create_id_mod, qui retournent ou créent les identifiants id_block et id_mod). 

CREATE OR REPLACE RULE ri_qry_add_plot AS
ON INSERT TO qry_add_plot DO INSTEAD  INSERT INTO
t_plot(id_block, plot, id_mod)
VALUES (
  fct_return_or_create_id_block(new.id_expe, new.block),
  new.plot,
  fct_return_or_create_id_mod(new.genotype, new.fungicide, new.nitrogen,
    new.degrain)
);

Une autre piste?

#3 Général » Erreur Insert utilisant des vues » 26/12/2016 16:51:07

Fanch
Réponses : 3

Bonjour,

Je suis plutôt un débutant, excusez le vocabulaire approximatif. J'ai changé d'ordinateur, et je me suis décidé à réécrire ma base de données. Sur mon ancienne machine, j'utilise des vues qui ne me posent pas de problème. Pour tester j'ai même relancé l'écriture de la base sur l'ancienne machine, aucune erreur. Depuis ma nouvelle installation, mes insert remontent cette erreur:

"DÉTAIL : Les vues qui lisent plusieurs tables ou vues ne sont pas automatiquement disponibles en écriture.
ASTUCE : Pour activer l'insertion dans la vue, fournissez un trigger INSTEAD OF INSERT ou une règle ON INSERT DO INSTEAD sans condition."

Et la vue utilisée est codée comme suit:

CREATE OR REPLACE VIEW qry_add_plot AS 
SELECT id_expe, block, plot, genotype, fungicide, nitrogen, degrain 
FROM t_block
JOIN t_plot ON t_block.id_block = t_plot.id_block
JOIN t_modality ON t_plot.id_mod = t_modality.id_mod;
CREATE OR REPLACE RULE ri_qry_add_plot AS
ON INSERT TO qry_add_plot DO INSTEAD  INSERT INTO
t_plot(id_block, plot, id_mod)
VALUES (
  fct_return_or_create_id_block(new.id_expe, new.block),
  new.plot,
  fct_return_or_create_id_mod(new.genotype, new.fungicide, new.nitrogen,
    new.degrain)
);

Comment rendre les vues automatiquement disponibles en écriture? J'aimerai éviter de toucher au code de mes vues utilisées en insertion, y a-t-il une option modifiable?

Pour ma version:
"PostgreSQL 9.4.9 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit"

Merci d'avance,
François

#4 Re : Général » Recherche date d'atteinte d'un seuil » 16/07/2014 14:10:17

Bonjour,
Merci pour votre aide, ci dessous la fonction finalement éditée :

DROP FUNCTION IF EXISTS fct_return_datestplus(date, integer, double precision) CASCADE;
CREATE OR REPLACE FUNCTION fct_return_datestplus(p_dat_initiale date, p_station integer, p_st double precision)
  RETURNS date AS
$BODY$
  DECLARE
  v_date date;
  BEGIN
      -- récupération de la date correspondante
	SELECT INTO v_date dat_meteo
	FROM (
	    SELECT dat_meteo, sum(tmoy) OVER (ORDER BY dat_meteo) as cumul
	    FROM qry_var_tmoy
	    WHERE dat_meteo > (p_dat_initiale) AND id_station = p_station
	) s
	WHERE s.cumul >= p_st
	ORDER BY dat_meteo
	LIMIT 1;
    RETURN v_date;
  END 
;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
COMMENT ON FUNCTION fct_return_datestplus(date, integer, double precision) IS '
fct_return_datestplus: fonction permettant de calculer la date a partir d''une 
date initiale et d''un cumul de temperature depuis cette date.
Remarques :
- le cumul commence le lendemain de la date initiale renseignee > (p_dat_initiale).
- pas de prise en compte d''une temperature de base ou temperature max 
EXAMPLE 1 :
SELECT fct_return_datestplus(''2007-05-08'', 1801, 30);
';

qry_var_tmoy est une table qui regroupe les température moyennes quotidiennes,
id_station est un identifiant de station meteo

#5 Général » Recherche date d'atteinte d'un seuil » 04/07/2014 11:16:01

Fanch
Réponses : 2

Bonjour,

Mon problème se pose sur des données climatiques de la forme:

id     dat_meteo        value
231  "2007-05-08"    15.35
232  "2007-05-09"    16.4
233  "2007-05-10"    17.8
234  "2007-05-11"    16.25
235  "2007-05-12"    16.35
236  "2007-05-13"    18.4
237  "2007-05-14"    13.7

Il s'agit d'une table ou à chaque jour est associée une valeur d'un paramètre, ici la température moyenne du jour. J'aimerais construire une fonction qui me permette, à partir d'une date initiale, de trouver la date à laquelle la somme des valeurs cumulées depuis cette date atteint au moins 200. Typiquement j'ai une date de floraison, par exemple le 2007-05-08, je veux connaitre la date 2007-05-08 + 200 degrés cumulés.

Le codage de fonction sous postgres est encore bien mystérieux pour moi, je ne sais pas vraiment comment m'y prendre ...
Merci

#6 Re : Général » Date mediane » 23/05/2014 09:35:15

PS : Finalement, la requête utilisée :

1/ Je crée la fonction médiane d'après http://wiki.postgresql.org/wiki/Aggregate_Median:

CREATE FUNCTION _final_median(anyarray) RETURNS float8 AS $$ 
  WITH q AS
  (
     SELECT val
     FROM unnest($1) val
     WHERE VAL IS NOT NULL
     ORDER BY 1
  ),
  cnt AS
  (
    SELECT COUNT(*) AS c FROM q
  )
  SELECT AVG(val)::float8
  FROM 
  (
    SELECT val FROM q
    LIMIT  2 - MOD((SELECT c FROM cnt), 2)
    OFFSET GREATEST(CEIL((SELECT c FROM cnt) / 2.0) - 1,0)  
  ) q2;
$$ LANGUAGE sql IMMUTABLE;
 
CREATE AGGREGATE median(anyelement) (
  SFUNC=array_append,
  STYPE=anyarray,
  FINALFUNC=_final_median,
  INITCOND='{}'
);

2/ Je l'utilise dans mon cas bien particulier en définissant une date d'origine antérieure à toute mes dates (en prenant le 1 mars 1900 dans mon cas) :

SELECT num_year, id_station, txt_variety, txt_stage,
	cast(median(dat_stage-'1900-03-01') as integer) + '1900-03-01'::date dat_stage_median
FROM t_plot JOIN t_stage ON t_plot.id_plot=t_stage.id_plot
GROUP BY num_year, id_station, txt_variety, txt_stage
ORDER BY num_year, id_station, txt_variety, txt_stage

Encore merci.

#7 Re : Général » Date mediane » 23/05/2014 09:18:41

Bonjour,
Encore merci pour vos suggestions. Quelques précisions sont ici à prendre en compte:
- Dans le cas bien particulier de mes dates de stade, c'est bien une date et non pas un délai. En effet, on cherche la date médiane d'atteinte du stade quelque soit la date de semis qui peut légèrement varier. Par contre utiliser une date de référence autre que le semis comme tu le proposes me paraît intéressant.
- Dans le cas de date de stade, la contrainte de calcul de la médiane nombre pair/impair à moins de sens, on peut s'en affranchir. On cherche véritablement la date à partir de laquelle au moins 50% des plants on passé le stade.

Enfin, j'ai testé ta requête meles, et celle ci me va complètement (le volume de mes données n'est pas énorme), et me donne un bon exemple que je tacherai d'utiliser par la suite. Pour la dernière proposition basée sur l'utilisation de la fonction median proposées ici http://wiki.postgresql.org/wiki/Aggregate_Median, je m'étais bien penché dessus et ne voyais pas comment l'utiliser dans mon cas, je vais regarder ça de plus prêt.

En tout les cas, merci pour vos réponses.

#8 Re : Général » Date mediane » 22/05/2014 12:08:59

Merci pour cette première solution qui me donne bien la date moyenne.

Néanmoins, la question est toujours ouverte pour le calcul d'une date médiane : date à laquelle 50% de mes plants de blé ont passé le stade en question.

#9 Général » Date mediane » 22/05/2014 10:46:50

Fanch
Réponses : 9

Bonjour,

Je cherche à calculer la date médiane (ou à défaut moyenne) par groupe, de la table suivante :
id  gr   date_stade
1   A     2014-05-22
2   A     2014-05-19
3   A     2014-05-20
4   B     2014-05-15
5   B     2014-05-13
6   B     2014-05-14
7   B     2014-05-16

Pour donner un peu de contexte, je suis des plants de blé (1 id = 1 plant de blé) qui ont atteint un stade particulier : l'épiaison qui se caractérise par une date. Je souhaite pour chaque variété (=chaque groupe), connaître la date à laquelle 50% de mes plants de blé ont passé le stade en question, soit la date médiane. J'ai déjà pas mal cherché et je ne trouve pas de solution adaptée pour calculer une date médiane au travers d'une requête ou de la création d'une fonction.

Le résultat attendu serait ici:
   gr    date_stade_mediane
1  A    2014-05-20
2  B    2014-05-14

Pouvez-vous m'aider ?

Merci.

Pied de page des forums

Propulsé par FluxBB