web-dev-qa-db-fra.com

Obtenez les 10e et 90e centiles par client

J'ai un tableau qui contient les clients et les scores (basé sur différents facteurs, non pertinent dans ce cas; un client peut avoir plusieurs scores), qui ressemble à ceci:

customer_id | score | score_giver_id
====================================
          1 | 100   | 1
          1 | 102   | 1
          1 | 101   | 1
          1 | 140   | 1
          2 | 131   | 3
          1 | 44    | 1
          3 | 223   | 1
          3 | 1     | 2
          3 | 201   | 1
          3 | 211   | 1
          3 | 231   | 1
          3 | 243   | 1

Le score_giver_id n'est pas pertinent, mais j'aimerais quand même le récupérer.

Dans l'exemple ci-dessus, lors de l'obtention du 50e centile, groupé par customer_id, le résultat devrait être (j'ai choisi le 50e centile dans cet exemple, car il illustre ce que je veux faire mieux):

customer_id | score | score_giver_id
====================================
          1 | 101   | 1
          2 | 131   | 3
          3 | 223   | 1

J'ai utilisé la méthode décrite ici .

J'ai besoin d'obtenir la valeur qui est au 10e centile, respectivement au 90e centile dans PostgreSQL. J'ai vu que depuis 9.4 il y a une fonction ntile, mais je ne comprends pas vraiment comment cela fonctionne, ce qu'elle fait et si cela m'aide.

J'ai trouvé un extrait de Nice pour MySQL, qui fonctionne (même s'il y a quelques mises en garde), mais j'aimerais utiliser des fonctions intégrées si disponibles (pour MySQL il n'y en a pas, d'où l'extrait).

13
Eduard Luca

Il semble que vous recherchiez la fonction d'agrégation percentile_disc() ordonnée.

Le documentation dit ce qui suit à ce sujet:

percentile_disc(fraction) WITHIN GROUP (ORDER BY sort_expression)

percentile discret: renvoie la première valeur d'entrée dont la position dans l'ordre est égale ou supérieure à la fraction spécifiée

La syntaxe est un peu étrange pour un agrégat, mais son utilisation est simple:

SELECT percentile_disc(0.9) WITHIN GROUP (ORDER BY score)
  FROM customer_score
 GROUP BY customer_id;

Vous définissez la colonne à partir de laquelle prendre le centile dans le ORDER BY clause.

22
dezso