Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#101 PL/pgSQL » RESOLU - utilisation d'un curseur » 03/03/2013 08:56:19
- damalaan
- Réponses : 6
Bonjour,
Pour m'apprendre à utiliser le PL/pgSQL, j'ai écrit cette fonction (qui présente peu d'intérêt en soi !) : le but est de parcourir la table tbl_analyse_ana et de récupérer le ana_id de chaque ligne puis de concaténer le résultat dans une variable de manière à avoir en sortie qqc du genre 1;2;3;4;5 etc.
Mais j'ai du louper qqc car la fonction ne génère pas d'erreur mais ne retourne rien
-- Function: test()
CREATE OR REPLACE FUNCTION test()
RETURNS TEXT AS
$BODY$
DECLARE
s RECORD;
s1 TEXT;
cur CURSOR FOR SELECT ana_id FROM tbl_analyse_ana;
BEGIN
open cur;
LOOP
FETCH cur INTO s;
s1 := s1 || ';' || s.ana_id || ';';
END LOOP;
CLOSE cur;
RETURN s1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION test()
OWNER TO postgres;merci de votre aide
#102 Re : Général » formatage de champ » 27/02/2013 17:20:19
je viens de faire ça
CASE imp_germes
WHEN '' THEN null
ELSE imp_germes
END::integer as imp_germeset ça marche
donc WHEN null THEN null génère une erreur
et WHEN '' THEN null fonctionne !?
merci de votre aide
#103 Re : Général » formatage de champ » 27/02/2013 17:11:57
les moufles c'est normal, il fait froid :-)
un exemple :
données avant formatage (type text)
10
<----
21
12
10
après formatage (type integer)
10
-1 <----
21
12
10
donc le vide prend la valeur de -1 alors qu'il doit rester vide.
je pense faire 2ème requete où je vais formater comme ça :
CASE imp_germes
WHEN -1 then null
ELSE imp_germes
END#104 Re : Général » formatage de champ » 27/02/2013 16:40:27
mais du coup les null qui doivent rester null ne sont plus null !!??
#105 Général » formatage de champ » 27/02/2013 16:32:18
- damalaan
- Réponses : 7
Bonjour
Suite à un import de fichier, je formate mes champs et j'ai un souci sur un champ qui au départ est en texte (et qui doit devenir entier) avec des lignes vides et d'autre avec des nombres.
extrait de ma requête :
CASE imp_germes
WHEN null THEN null
ELSE imp_germes::integer
ENDERREUR: syntaxe en entrée invalide pour l'entier : « »
********** Erreur **********
ERREUR: syntaxe en entrée invalide pour l'entier : « »
État SQL :22P02
j'ai testé sur un champ où je suis sûr qu'il n'y a pas de ligne vide et celà fonctionne.
Merci de votre aide
#106 Re : Général » classement avec rattrapage » 05/12/2012 14:42:08
Je me réponds à moi même , non pas que j'ai trouvé la solution hélas mais pour corriger une erreur dans le jeu de donnée en exemple
Concernant les 9 dernières valeurs (sur mars avril et mai), pour que mon exemple fonctionne je remplace le 1334 du 07/03 par 1247.
Voici un exemple de données avec une seuil fixe à 1250
ligne produit date defaut moy classement
ligneA 993001 07/02/11 00:00 1710
ligneA 993001 18/02/11 00:00 1687
ligneA 993001 23/02/11 00:00 1249 1533.055498 B
ligneA 993001 07/03/11 00:00 1247
ligneA 993001 18/03/11 00:00 728
ligneA 993001 23/03/11 00:00 954 966.1131897 A
ligneA 993001 06/04/11 00:00 856
ligneA 993001 15/04/11 00:00 1005
ligneA 993001 27/04/11 00:00 934 929.6701802 A
ligneA 993001 04/05/11 00:00 974
ligneA 993001 13/05/11 00:00 989
ligneA 993001 26/05/11 00:00 1111 1022.876268 A
ligneA 993001 07/06/11 00:00 1167
ligneA 993001 13/06/11 00:00 1212
ligneA 993001 29/06/11 00:00 1400 1255.742242 B==>AA chaque fois que je calcule une moyenne (avec un group by sur ligne, produit, mois), j'établis un premier classement avec une instruction case when==> ça je gère!
ensuite, il faut que j'aille compter le nombre de fois ou le produit x sur la ligne y a plus de 1250 defauts relevés sur les 9 derniers comptages précédent le mois "moyenné" (donc sur les 3 mois auparavant pour faire plus simple). Et si ce comptage est = 0, alors je peux rattraper le classement et le remonter d'un cran.
Est-ce plus clair ainsi?
#107 Général » classement avec rattrapage » 24/11/2012 21:54:37
- damalaan
- Réponses : 1
Bonjour,
J'ai le code suivant qui me renvoie un classement de produit en fonction d'une moyenne
représentant le nombre de defaut
with
moy as (select res_ligne, res_prod, to_char(res_date, 'YYYYMM') as mois, exp(avg(ln(res_defaut))) as moy_geo
from tbl_resultat_res
group by res_ligne, res_prod, to_char(res_date, 'YYYYMM')),
class as(
select res_ligne, res_prod, mois, moy_geo,
case
when moy_geo <=1250 then 'A'
when moy_geo > 1250 and moy_geo <= 1500 then 'B'
when moy_geo > 1500 and moy_geo <= 1750 then 'C'
when moy_geo > 1750 and moy_geo <= 2000 then 'D'
else 'E'
end as class
from moy)
select * from class
;
maintenant je voudrais introduire un système de rattrapage du genre :
soit : si un produit est classé en B C D ou E et si sur les 3 derniers mois 7 comptages de defaut sur 9
sont inférieur à 1250 alors je le surclasse c'est à dire que qu'un B je le passe en A, un C en B, etc
soit je prends comme seuil de rattrapage glissant :
pour passer de B en A ==>7 résultats <=1250
de C en B ==> 7 résultats <=1500
de D en C==> 7 résultats <=1750
de E en D ==> 7 résultats <= 2000
je ne me suis pas encore décidé sur le mode de rattrapage, mais là je bloque sur les 2!
Voici un exemple de données avec une seuil fixe à 1250
ligne produit date defaut moy classement
ligneA 993001 07/02/11 00:00 1710
ligneA 993001 18/02/11 00:00 1687
ligneA 993001 23/02/11 00:00 1249 1533.055498 B
ligneA 993001 07/03/11 00:00 1334
ligneA 993001 18/03/11 00:00 728
ligneA 993001 23/03/11 00:00 954 974.8666074 A
ligneA 993001 06/04/11 00:00 856
ligneA 993001 15/04/11 00:00 1005
ligneA 993001 27/04/11 00:00 934 929.6701802 A
ligneA 993001 04/05/11 00:00 974
ligneA 993001 13/05/11 00:00 989
ligneA 993001 26/05/11 00:00 1111 1022.876268 A
ligneA 993001 07/06/11 00:00 1167
ligneA 993001 13/06/11 00:00 1212
ligneA 993001 29/06/11 00:00 1400 1255.742242 B==>A
le dernier est rattrapable car sa moyenne est supérieure au seuil, mais sur les 9 resultats de comptage des mois précedent le calcul de la moyenne, aucun n'est supérieure à 1250
#108 Re : Général » comptage de valeurs consécutives » 12/11/2012 21:44:10
Je pense que je passerais par les fonctions de fenêtrage et notamment les fonctions lag ou lead pour comparer les lignes entre elles
pour la syntaxe exacte, regardez la doc, car comme ça j'aurais du mal à vous donner un code correct!
#109 Re : Général » Problème de connexion » 08/10/2012 11:51:12
Il me semble que cela m'est déjà arrivé sur un portable équiper de windows7.
Et je crois que la solution est de mettre le répertoire data ailleurs que dans le Program Files (à l'installation): apparemment c'est l'espace du program files qui pourrait parfois poser problème
Je ne sais plus où j'avais trouver l'astuce l'info :-(
#110 Re : Général » Calcul de moyenne sur 2 mois » 13/09/2012 09:45:16
merci jpargudo pour cette démo!
je n'ai pas opté pour votre solution
Je crée dans une requête le mois de "référence" de cette manière, et après je l'utilise pour mon regroupement
Pardon pour la trituration de la date, mais elle est stockée d'une manière particulière qui m'oblige à faire des imbrications de fonction pour en retirer qqc (cf la plupart de mes posts sur ce forum!!)
CASE extract(month from (to_timestamp((tbl_tournee_trn.trn_date_prel / 100)::text, 'YYMM'::text)))::integer%2
WHEN 0 THEN to_timestamp((tbl_tournee_trn.trn_date_prel / 100)::text, 'YYMM'::text)+ '1 month'::interval
WHEN 1 THEN to_timestamp((tbl_tournee_trn.trn_date_prel / 100)::text, 'YYMM'::text)
END as mois_refj'extrais le mois, un modulo 2 pour voir s'il est pair ou impair;
si pair, j'ajoute 1 mois
si impair je garde le même mois
celà me semble plus simple!
#111 Général » Calcul de moyenne sur 2 mois » 12/09/2012 11:27:27
- damalaan
- Réponses : 4
Bonjour,
Il faut que je calcule une moyenne en faisant un regroupement sur un champ de type date mais la particularité est que le calcul doit se faire au bimestre (2mois, le 2ème mois étant toujours impair).
Par exemple, il me faut calculer la moyenne pour Décembre 2011 et Janvier 2012, puis Février et Mars 2012, Avril et Mai 2012, etc.
Vu ce regroupement un peu particulier, je n’arrive à voir comment faire !
Merci d’avance
#112 Re : Général » problème de connexion ODBC » 06/09/2012 13:16:47
je me reponds à moi même, la pause déjeuner m'ayant été bénéfique!!
finalement c'est bien un problème d'ip : dans la chaine ODBC, l'ip est présente
j'ai donc modifié la connexion odbc en localhost, lié de nouveau toutes les tables et vues nécessaires dans le fichier Access avec cette nouvelle connexion ODBC et ça fonctionne!
#113 Général » problème de connexion ODBC » 06/09/2012 12:29:07
- damalaan
- Réponses : 4
Bonjour
j'ai installé une base Postgres sur un portable pour faire une démo en réunion.
comme l'UI tourne sous Access, il faut aussi configurer une connexion ODBC.
j'ai attribué la même adresse ip au portable quelle celle du serveur ou tourne postgres pour ne pas avoir à refaire l'UI, sauf que ça ne fontionne pas:
je configure ma connexion ODBC via les outils d'administations de windows et quand je teste la connexion cela marche en "localhost" mais pas avec l'ip 192.168.1.64!!
j'ai modifié les fichiers pg_hba.conf
host Indext all 192.168.0.0/0 md5comme le portable n'est pas connecté à aucun réseau, je pense que ça vient de là! quand je fais un ipconfig, il ne me renvoie pas d'adresse ip
merci d'avance
#114 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 17/08/2012 08:28:58
NICKEL!!!
Avec le même volume de données (soit plus de 530 000 lignes), je gagne 20s d'exécution (je passe de 36s à 17s)
Tout en sachant que je ne travaille la plupart du temps que sur 50 000 à 70 000 lignes, la requête finale prend alors moins d'1s. ![]()
Avec tous mes remerciements !
#115 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 16/08/2012 16:25:52
je suis bien d'accord que supprimer des requêtes puis les recréer n'est pas très ....pro
Le principe que j'ai actuellement :
R1 : calcul des écarts entre les valeurs d'une même colonne en utilisant une fonction WINDOW
R2 : calcul à partir de l'écart calculé en R1 un écart type, avec un regroupement sur 4 colonnes (espèce, usine, tournée, mois)
R3 : calcul à partir de l'écart-type calculé en R2, la moyenne des écart types avec un regroupement sur 2 colonnes (espèce, mois)
R4 : comparaison des écart types obtenus en R2 avec la moyenne R3 pour définir des alertes
R5 : comparaison des alertes identifiées en R4 sur 2 mois consécutifs, afin d'identifier la récurrence éventuelle d'apparition des alertes
J'ai commencé à essayer de rassembler tous mes requêtes en 1 seule mais ça devient rapidement compliqué! J'en suis resté à R2!
J'imagine donc qu'il va falloir que je poursuive mon idée en PL/pgSQL. Est-il possible de créer un genre de requête temporaire en PL/pgSQL? (et est-ce une bonne idée?)
#116 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 10/08/2012 08:12:50
Je crois n'avoir pas bien compris le Explain : effectivement je suis à 2.5s d'exécution après les modifs d'index et de mémoire.
mais le select en lui même n'a pas tellement changé : pg Admin renvoie
Je voudrais donc poursuivre sur mon idée d'hier de n'utiliser que les éléments nécessaires et non toute une table.
Faut-il que je crée une fonction qui fasse toutes requêtes d'un seul coup en les supprimant et recréant à chaque fois?
#117 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 09/08/2012 16:33:47
Oui mais au global ça dure toujours une trentaine de sec!
Je pense à autre chose : cette fameuse vue me sert à 4 autres en cascade(la vue 1 sert à la vue2, la vue 2 sert à la vue 3 etc), et dès la première je renvoie 500000lignes avec le
WHERE tbl_tournee_trn.trn_date_prel > 100000Or je n'ai que très rarement besoin de travailler sur tout ça. Il me faut juste des stats sur 3 mois, donc par exemple pour Aout 2012, il faudrait que je récupère juste les données depuis juin 2012
il me faudrait qqc du genre
WHERE to_timestamp(tbl_tournee_trn.trn_date_prel/100, 'yymm') between Moncritère and Moncritère-'3 Month'::interval)Il faudrait que je puisse paramétrer ce critère à chaque fois,.............ce que je ne sais pas faire
et pour avoir tester 'à la main', j'en suis à 2 à 3s d'exécution ce qui nickel pour l'utilisateur
#118 Re : Général » requête avec where sur année et mois d'un timestamp » 08/08/2012 15:15:42
Bizarre d'avoir une date sur une colonne appelée mois : c'est une "fausse" date car il n'y a que le mois et l'année qui m'intéresse, le jour est toujours à 1
Mais comme suggéré par Marc Cousin dans une réponse à un de mes posts précédents, il est plus simple de faire des calculs :
dans la table de départ, le mois est stocké sous forme numérique du genre 1208, mais cela pose problème pour faire des calcul du genre 1201 - 1mois; je l'ai donc passé en timestamp (mais je n'ai pas changé le nom!)
Passé de
EXTRACT(YEAR FROM B.mois) = EXTRACT(YEAR FROM A.mois)
AND
EXTRACT(MONTH FROM B.mois) = EXTRACT(MONTH FROM A.mois)à
to_char(B.mois, 'YYYYMM') = to_char(A.mois, 'YYYYMM')est tout de même un peu plus simple!
merci
#119 Général » requête avec where sur année et mois d'un timestamp » 08/08/2012 11:30:54
- damalaan
- Réponses : 2
Bonjour,
J'ai la requête suivante
SELECT
A.trn_esp,
A.trn_tournee,
A.trn_usine,
B.mois,
A."EtTournee",
B."MoyLabo"*2 as Indicateur,
CASE
WHEN A."EtTournee" > (2::numeric * B."MoyLabo") THEN 'Alerte'::text
ELSE 'ok'::text
END AS "Alerte"
FROM
"vw_simuMoisMoyLabo" B,
"vw_simuMoisEtTournee" A
WHERE
(
B.trn_esp = A.trn_esp
AND
(
EXTRACT(YEAR FROM B.mois) = EXTRACT(YEAR FROM A.mois)
AND
EXTRACT(MONTH FROM B.mois) = EXTRACT(MONTH FROM A.mois)
)
)
ORDER BY trn_esp, "Alerte";Je voudrais savoir si ce que j'ai fait sur le WHERE est judicieux ou non.
Y a t il un autre moyen de dire : je veux les lignes des tables A et B en faisant une jointure sur le mois et l'année d'un timestamp?
#120 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 08/08/2012 11:20:23
Effectivement en plaçant un index sur la colonne trn_date_prel, et en augmentant la mémoire (50MB), je gagne pas grand chose : 1 à 2 s.
Merci pour ces infos.
#121 Re : Optimisation » Recherche d'optimisation sur calcul de requete » 03/08/2012 15:17:08
taille table tbl_tournee_trn : Lignes estimées 73145
taille table tbl_valeur_mg : Lignes estimées 650283
voilà pour le explain
"WindowAgg (cost=130671.82..151806.02 rows=650283 width=32) (actual time=2739.974..4027.162 rows=496831 loops=1)"
" -> Sort (cost=130671.82..132297.53 rows=650283 width=32) (actual time=2739.920..3132.560 rows=496831 loops=1)"
" Sort Key: tbl_valeur_mg.mg_matricule, tbl_tournee_trn.trn_esp, tbl_tournee_trn.trn_date_prel"
" Sort Method: external merge Disk: 19624kB"
" -> Hash Join (cost=2787.50..36762.70 rows=650283 width=32) (actual time=181.034..1570.746 rows=496831 loops=1)"
" Hash Cond: (tbl_valeur_mg.trn_id = tbl_tournee_trn.trn_id)"
" -> Seq Scan on tbl_valeur_mg (cost=0.00..11284.83 rows=650283 width=20) (actual time=0.052..238.358 rows=650283 loops=1)"
" -> Hash (cost=1551.74..1551.74 rows=63901 width=28) (actual time=58.872..58.872 rows=62807 loops=1)"
" Buckets: 2048 Batches: 4 Memory Usage: 794kB"
" -> Seq Scan on tbl_tournee_trn (cost=0.00..1551.74 rows=63901 width=28) (actual time=2.371..28.166 rows=62807 loops=1)"
" Filter: (trn_date_prel > 100000)"
"Total runtime: 4120.821 ms"#122 Optimisation » Recherche d'optimisation sur calcul de requete » 03/08/2012 14:51:47
- damalaan
- Réponses : 13
Bonjour
j'ai la requete suivante basée sur 2 table (en 1-n) dont la structure est également ci-dessous
la requête :
CREATE OR REPLACE VIEW view_ecart AS
SELECT tbl_tournee_trn.trn_esp, tbl_tournee_trn.trn_date_prel, tbl_tournee_trn.trn_tournee, tbl_tournee_trn.trn_chauffeur, tbl_tournee_trn.trn_usine, tbl_valeur_mg.mg_matricule, tbl_valeur_mg.mg_val,
CASE lag(tbl_valeur_mg.mg_val, 1) OVER (PARTITION BY tbl_valeur_mg.mg_matricule ORDER BY tbl_tournee_trn.trn_esp, tbl_tournee_trn.trn_date_prel)
WHEN 0 THEN NULL::numeric
ELSE
CASE tbl_valeur_mg.mg_val
WHEN 0 THEN NULL::numeric
ELSE tbl_valeur_mg.mg_val - lag(tbl_valeur_mg.mg_val, 1) OVER (PARTITION BY tbl_valeur_mg.mg_matricule ORDER BY tbl_tournee_trn.trn_esp, tbl_tournee_trn.trn_date_prel)
END
END AS ecart
FROM tbl_valeur_mg
JOIN tbl_tournee_trn USING (trn_id)
WHERE tbl_tournee_trn.trn_date_prel > 100000;
ALTER TABLE view_ecart OWNER TO postgres;table du coté 1:
CREATE TABLE tbl_tournee_trn
(
trn_date_prel integer NOT NULL,
trn_esp integer NOT NULL,
trn_tournee integer NOT NULL,
trn_usine integer NOT NULL,
trn_id bigserial NOT NULL,
trn_chauffeur integer,
CONSTRAINT "clé_primaire" PRIMARY KEY (trn_id),
CONSTRAINT "clé_2" UNIQUE (trn_date_prel, trn_esp, trn_tournee, trn_usine)
)
WITH (
OIDS=FALSE
);
ALTER TABLE tbl_tournee_trn OWNER TO postgres;table du coté n
CREATE TABLE tbl_valeur_mg
(
mg_id bigserial NOT NULL,
trn_id bigserial NOT NULL,
mg_matricule integer NOT NULL,
mg_val numeric(4,1) NOT NULL,
CONSTRAINT pk PRIMARY KEY (mg_id),
CONSTRAINT fk FOREIGN KEY (trn_id)
REFERENCES tbl_tournee_trn (trn_id) MATCH FULL
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);
ALTER TABLE tbl_valeur_mg OWNER TO postgres;
-- Index: index_mg
-- DROP INDEX index_mg;
CREATE INDEX index_mg
ON tbl_valeur_mg
USING btree
(trn_id, mg_matricule);Il y a un index de positionner, mais l'est-il bien?
la requete met une 30aine de seconde pour renvoyer 500000 lignes
je fais souvent appel à cette requête car je travaille beaucoup sur le calcul qui en est issu et je recherche un moyen d'augmenter un peu la rapidité
merci d'avance
#123 Re : Général » histoire de count » 25/06/2012 14:30:40
Finalement, j'ai opté pou ça :
select count(*) from
(
select t1.usine from tbl_test_tst t1 inner join tbl_test_tst t2
on t1.usine = t2.usine
WHERE t1.esp=1 and t2.esp =2
) as t;et j'obtiens bien 1 (1 usine a esp=1 et esp = 2)
La table que j'ai présenté était pour l'exemple, en réalité, j'ai une jointure dès le début, ce qui me donne un truc du genre :
SELECT COUNT(*) FROM
(SELECT DISTINCT ta.chf_id, ta.trn_esp
FROM
(SELECT DISTINCT chf_id, trn_esp
FROM
tbl_chauffeur_chf t1 INNER JOIN tbl_tournee_trn t2
ON t1.chf_id = t2.trn_chauffeur
WHERE trn_date_prel >110400 AND chf_archive = FALSE) ta
INNER JOIN
(SELECT DISTINCT chf_id, trn_esp
FROM
tbl_chauffeur_chf t1 INNER JOIN tbl_tournee_trn t2
ON t1.chf_id = t2.trn_chauffeur
WHERE trn_date_prel >110400 and chf_archive = FALSE) tb
ON ta.chf_id = tb.chf_id
WHERE ta.trn_esp = 1 and tb.trn_esp=2
) t;Le but étant de savoir quel chauffeur a tourné sur trn_esp = 1 ET trn_esp=2
Si vous avez plus simple, je suis preneur!
#124 Re : Général » histoire de count » 21/06/2012 14:21:01
leTrucPasCompris est :
le nombre d'usine ayant comme 1 et 2 dans la colonne esp
dans ma minitable (en réel, j'ai qq centaines de lignes!), je n'ai qu'une usine ayant 1 et 2
je peux reformuler différemment pour éviter la confusion avec cette forme::
1621;b
1621;a
1622;a
1623;a
1624;b
combien y a t il d'usine ayant a ET b, réponse 1
#125 Général » Calculer une fréquence » 21/06/2012 13:48:44
- damalaan
- Réponses : 1
Soit les valeurs suivantes :
id1;id2;matricule;valeur
293469;19659;11253;39.9
Pour ceux qui connaissent Excel, je cherche à reproduire la fonction matricielle Fréquence(matrice_valeurs;matrice_intervalles)
293470;19659;13207;42.5
293471;19659;5026;37.2
293472;19659;11190;44.5
293473;19659;10460;50.7
293474;19659;11107;45.4
293475;19659;15868;42.2
293476;19659;5084;45.3
293477;19659;5041;46.1il me faut récupérer le nombre de valeurs par tranches suivantes:
39
40
41
42
43
44
45pour avoir un résultat :
39 1
40 1
41 0
42 0
43 2
44 0
45 1ce qui signifie que j'ai une valeur <= à 39, 1 entre dans l'intervalle ]39-40], 0 dans ]40-41] etc jusqu'à 1 dans ]44,45]
pour la partie intervalle, je pense utiliser qqc du genre
select * from generate_series(39,45,1);