IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PostgreSQL Discussion :

Connaître la médiane de plusieurs échantillons en une requête ( PL/R ) [9.2]


Sujet :

PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 6
    Par défaut Connaître la médiane de plusieurs échantillons en une requête ( PL/R )
    Bonjour à tous,

    Quelques infos pratiques avant de commencer (je ne sais pas si toutes les infos seront utiles)

    OS : Windows 7 (64 bits)
    Processeur : Intel Core i7
    RAM : 12 Go
    Version de PostGreSQL : 9.3 (installé dans D:\Programmes\PostgreSQL\9.3)
    Version de R : 3.0.2 (installé dans C:\Program Files\R\R-3.0.2)
    Interface d'utilisation de PostGreSQL : pgAdmin III
    Forme d'utilisation de PostGreSQL : Utilisation en local uniquement pour du SQL
    Niveau en SQL : Novice - J'ai quand même les notions de base

    Mon problème

    Je dispose d'une base de données de ce type (en plus complet bien entendu ~53 000 lignes) :

    Nom : tableau_bdd.jpg
Affichages : 238
Taille : 42,8 Ko

    Via une requête SQL, pour chaque OBS_ID, je souhaite connaître la valeur médiane du critère ANNEE.

    Il semblerait que la solution à mon problème soit toute trouvée en passant par le langage PL/R (comme indiqué sur ce lien).

    La première difficulté aura été d'installer l'extension PLR dans PostGreSQL. J'avais pas mal de messages d'erreur liés à des manques dans le répertoire lib de PostGreSQL. J'ai trouvé des indications pour régler tout ça en consultant ces 2 liens :
    - www.bostongis.com - Installing PL/R
    - georezo.net - Problème chargement langage PLR pour PostGreSQL 9.0

    Remarque : Pour que ça fonctionne bien chez moi, il aura fallu que je redémarre le PC après avoir édité les variables d'environnement et placé les bons ddl dans le dossier lib de PostGreSQL.

    Donc, une fois le langage PL/R installé dans PostGreSQL et prêt à l'emploi, j'ai testé via l'exemple donné dans le 1er lien indiqué en saisissant les requêtes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    CREATE OR REPLACE FUNCTION r_median(_float8)
    RETURNS float AS 'median(arg1)'
    LANGUAGE 'plr';
     
    CREATE AGGREGATE median (
    sfunc = plr_array_accum,
    basetype = float8,
    stype = _float8,
    finalfunc = r_median
    );
     
    CREATE TABLE foo(f0 int, f1 text, f2 float8);
    INSERT INTO foo values(1,'cat1',1.21);
    INSERT INTO foo values(2,'cat1',1.24);
    INSERT INTO foo values(3,'cat1',1.18);
    INSERT INTO foo values(4,'cat1',1.26);
    INSERT INTO foo values(5,'cat1',1.15);
    INSERT INTO foo values(6,'cat2',1.15);
    INSERT INTO foo values(7,'cat2',1.26);
    INSERT INTO foo values(8,'cat2',1.32);
    INSERT INTO foo values(9,'cat2',1.30);
    Jusque là tout va bien. Et lorsque je saisis la requête finale, censée me donner le résultat attendu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT f1, median(f2) FROM foo GROUP BY f1 ORDER BY f1;
    J'ai droit au message d'erreur suivant :

    ERREUR: R interpreter expression evaluation error
    DETAIL: Error in (PLR32995 <- function(arg1) { : could not find function "median"
    CONTEXT: In PL/R function r_median
    ********** Erreur **********

    ERREUR: R interpreter expression evaluation error
    État SQL :22000
    Détail :Error in (PLR32995 <- function(arg1) { : could not find function "median"
    Contexte : In PL/R function r_median
    Avec mes maigres compétences et malgré de nombreuses recherches sur le net, je n'ai pas réussi à trouver l'origine de ce problème et la solution pour le régler... Si parmi vous il y en a qui sauraient m'aider, je les remercie par avance.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Pour PL/R je ne saurais pas vous aider, mais la fonction médiane vous pouvez l'implémenter en SQL :
    http://wiki.postgresql.org/wiki/Aggregate_Median

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    Faites un PERCENT_RANK() (fonction de fenêtrage) et cherchez la valeur la plus proche de 0.5.
    À lire, sur les fonctions de fenêtrage : http://sqlpro.developpez.com/article...clause-window/

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 6
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Pour PL/R je ne saurais pas vous aider, mais la fonction médiane vous pouvez l'implémenter en SQL :
    http://wiki.postgresql.org/wiki/Aggregate_Median
    Merci beaucoup Waldar, cela a complètement réglé mon problème !

    Éventuellement, pour ceux que ça pourrait intéresser, voici ce que j'ai fait

    Surpression de la fonction median que j'avais créé lors de la tentative d'utilisation du langage PL/R avec la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DROP AGGREGATE median (float8);
    Pour mémoire, pour voir si la fonction existe bien, on peut le savoir avec la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM pg_proc WHERE "proname" LIKE 'median';
    J'ai ensuite rentré les requêtes indiquées dans le lien de Waldar :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    CREATE OR REPLACE FUNCTION _final_median(numeric[])
       RETURNS numeric AS
    $$
       SELECT AVG(val)
       FROM (
         SELECT val
         FROM unnest($1) val
         ORDER BY 1
         LIMIT  2 - MOD(array_upper($1, 1), 2)
         OFFSET CEIL(array_upper($1, 1) / 2.0) - 1
       ) sub;
    $$
    LANGUAGE 'sql' IMMUTABLE;
     
    CREATE AGGREGATE median(numeric) (
      SFUNC=array_append,
      STYPE=numeric[],
      FINALFUNC=_final_median,
      INITCOND='{}'
    );
    Ce qui m'a permis de faire fonctionner la requête finale (testé sur l'exemple de table foo évoquée dans le 1er post) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT f1, median(f2) FROM foo GROUP BY f1 ORDER BY f1;
    Et pour finir, juste une petit remarque pour préciser qu'il faut bien veiller à ce que le type des données pour lesquelles on souhaite connaître la médiane soit identique à celui renseigné dans la fonction median. Dans le cas présent, il fallait que les données f2 soient de type numeric. Par conséquent pour créer la table foo, la requête correcte était la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE foo(f0 int, f1 text, f2 numeric);
    Citation Envoyé par SQLpro Voir le message
    Faites un PERCENT_RANK() (fonction de fenêtrage) et cherchez la valeur la plus proche de 0.5.
    À lire, sur les fonctions de fenêtrage : http://sqlpro.developpez.com/article...clause-window/

    A +
    Merci également SQLpro ! Je testerai cette solution pour comparer. Par ailleurs, votre lien m'a permis de découvrir qu'il existait une fonction NTILE qui pourrait m'être bien utile pour connaître les déciles et centiles !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Plusieurs SUM dans une requête
    Par pj69100 dans le forum Requêtes
    Réponses: 6
    Dernier message: 02/01/2007, 10h34
  2. Sous-requête excutée plusieurs fois dans une requête
    Par sheridan31 dans le forum Oracle
    Réponses: 8
    Dernier message: 03/07/2006, 16h18
  3. [MySQL] Sélection de plusieurs lignes en une requête
    Par kalash_jako dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/05/2006, 19h43
  4. plusieurs insert en une requête...
    Par maniaco_jazz dans le forum Requêtes
    Réponses: 9
    Dernier message: 06/12/2005, 17h06
  5. Plusieurs jointures dans une requête sql
    Par Pero dans le forum Langage SQL
    Réponses: 3
    Dernier message: 21/09/2005, 20h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo