Les Quartiles de requête SQL
J'ai une table très très simple comme ça:
CREATE TABLE IF NOT EXISTS LuxLog (
Sensor TINYINT,
Lux INT,
PRIMARY KEY(Sensor)
)
Il contient des milliers de journaux à partir de différents capteurs.
Je voudrais avoir Q1 et Q3 pour tous les capteurs.
Je peux faire une requête pour chaque donnée, mais il serait mieux pour moi d'avoir une requête pour tous les capteurs (T1 et T3 arrière à partir d'une requête)
J'ai pensé que ce serait une opération assez simple, comme les quartiles sont largement utilisés et l'une des principales variables statistiques dans le calcul de fréquence. La vérité est que j'ai trouvé des charges de trop compliqué de solutions, alors que j'espérais trouver quelque chose de propre et simple.
Quelqu'un peut me donner un indice?
Edit: C'est un morceau de code que j'ai trouvé en ligne, mais il ne fonctionne pas pour moi:
SELECT SUBSTRING_INDEX(
SUBSTRING_INDEX(
GROUP_CONCAT( -- 1) make a sorted list of values
Lux
ORDER BY Lux
SEPARATOR ','
)
, ',' -- 2) cut at the comma
, 75/100 * COUNT(*) -- at the position beyond the 90% portion
)
, ',' -- 3) cut at the comma
, -1 -- right after the desired list entry
) AS `75th Percentile`
FROM LuxLog
WHERE Sensor=12
AND Lux<>0
Je suis 1 comme valeur de retour, alors que ce devrait être un nombre qui peut être divisé par 10 (10,20,30.....1000)
"J'ai pensé que ce serait une opération assez simple, comme les quartiles sont largement utilisés et l'une des principales variables statistiques relatives à la fréquence de calcul." Ce n'est pas une très bonne base pour la prévision de la facilité de la tâche. Le calcul des quartiles (et même juste médianes) est opérationnel compliqué par rapport à, disons, le calcul de moyens.
Vous avez raison, mais je me rapproche de SQL maintenant et depuis que je suis habitué à d'autres de haut niveau des langages de programmation l'absence d'un logiciel de statistiques est de me faire souffrir.
SQL n'est pas bien caractérisé comme un programmation langue. C'est une définition de données et langage de manipulation de données, basé sur un modèle de données relationnel. Bien que SQL en général et plus certaines implémentations ne présente certaines caractéristiques réalisé à la commande, le modèle sous-jacent est basé sur la (non ordonnée). Cela ne correspond pas bien avec certains types de tâches, telles que l'informatique quartiles. Cela ne signifie pas que vous pas effectuer de tels calculs en SQL, mais pour certaines tâches, vous êtes mieux de couplage SQL avec une autre langue.
MySQL en particulier se trouve être particulièrement limitée pour de telles tâches, comme il lui manque plusieurs caractéristiques communes qui rendra la tâche plus facile (les fonctions de la fenêtre, les expressions de table communes, diverses autres fonctions: même en faisant abstraction de
NTILE()
).OriginalL'auteur Hamma | 2015-07-03
Vous devez vous connecter pour publier un commentaire.
Voir SqlFiddle : http://sqlfiddle.com/#!9/accca6/2/6
Remarque : pour les sqlfiddle j'ai généré 100 lignes, chaque entier compris entre 1 et 100 est doté d'une ligne, mais c'est un ordre aléatoire (dans excel).
Voici le code :
EDIT :
Raisonnement sous-jacent est comme suit :
Pour le quartile 1 nous voulons obtenir 25% à partir du haut, donc nous voulons savoir combien de lignes il y a, c'est :
Maintenant que nous savons le nombre de lignes, nous voulons savoir ce qui est de 25%, c'est cette ligne :
Puis de trouver un quartile nous voulons commander le LuxLog table par Lux, puis pour obtenir le numéro de ligne "@quartile", pour ce faire nous avons fixé le DÉCALAGE de @quartile-à-dire que nous voulons commencer notre sélectionnez le numéro de ligne @quartile et nous dire la limite de 1-à-dire que nous voulons récupérer qu'une seule ligne. C'est :
Nous font (presque) la même chose pour l'autre quartile, mais plutôt que de commencer par le haut (à partir des valeurs supérieures à la plus faible) nous commençons par le bas (il explique l'ASC).
Mais pour l'instant nous avons juste les chaînes stockées dans les variables @sql_q1 et @sql_q3, de sorte que les concaténer, nous avons de l'union les résultats des requêtes, nous avons préparer la requête et de l'exécuter.
désolé, je pensais qu'il n'y avait pas 2 lignes avec le même capteur ^^ Voici un code qui fonctionne pour un Capteur (voir édité code), je suis en train de travailler sur l'une des sorties pour tous les capteurs, je vous dis quand c'est fait.
Je vais essayer ça dès que je peux. Ne vous embêtez pas pour la sortie de tous les capteurs, comme je l'ai peut exécuter des requêtes différentes pour chaque capteur. L'important pour moi est d'obtenir les quartiles de la requête au lieu d'obtenir des milliers de raws arrière à partir d'une requête, puis calculer moi-même.
Si nous prenons la définition de w3schools par exemple (sur Google) : "La contrainte de CLÉ PRIMAIRE identifie de manière unique chaque enregistrement dans une table de base de données.". Il signifie que chaque ligne a une valeur différente dans le champ de clé primaire. Il vous permet de vous identifier de manière unique une ligne. C'est pourquoi il est étrange d'avoir la CLÉ PRIMAIRE qui est redondant. Il est plus probable une clé étrangère, cela signifie que le champ de clé étrangère dans la table des liens vers une clé primaire dans une autre table. Voir : stackoverflow.com/questions/1692538/...
Peut-être que vous n'avez pas besoin d'une clé primaire, MAIS vous avez probablement besoin d'un index (voir l'utilité de l'index : stackoverflow.com/questions/1108/... ). Il fera les résultats de votre requête plus rapide. En outre, vous ne peut tout simplement pas utiliser d'index primaire sur votre base de données puisque vous avez plusieurs lignes qui ont la même clé. Il retourne une erreur "Duplicate entry '101' for key 'PRIMARY'" quand j'ai essayé.
OriginalL'auteur Pholochtairze
Bien à une utilisation en NTILE est très simple, mais il est un Postgres Fonction. En gros, vous avez juste à faire quelque chose comme ceci:
Voici un exemple simple que j'ai fait pour vous sur SQLFiddle: http://sqlfiddle.com/#!15/7f05a/1
Dans MySQL, vous devez utiliser RANG... Voici le SQLFiddle: http://www.sqlfiddle.com/#!2/d5587/1 (cela vient de la Question sur le lien ci-dessous)
Cette utilisation de MySQL RANG() provient de la Stackoverflow la réponse ici: Fonction rang dans MySQL
Chercher la réponse par Salman A.
NTILE()
pour ce travail, c'est que MySQL ne l'ont pas fait (et la question est balisé mysql).Oui, vous avez raison. Je suis de l'utilisation de MySQL et je viens de remarquer que NTILE() n'est pas une fonction MySQL. Je suis désolé pour perdre votre temps.
Ce n'est pas une perte de temps. J'ai ajouté un lien vers la discussion de la fonction RANG dans Mysql. Que vous offre ce que vous cherchez.
J'ai essayé l'exemple sur ma table, et j'ai eu les résultats regroupés avec le grade. Je suppose que pour obtenir les quartiles-je demander à un numéro de rang totalranks*0,25 et totalranks*0.75?
Je suppose que
NTILE
a été ajouté pourMySQL 8
OriginalL'auteur
Quelque chose comme ça devrait le faire:
Voici l'exemple complet:
Édité le rang réponse que j'ai donné pour revenir juste une ligne pour chaque ntile.
Je reçois toujours une table avec des milliers de lignes à votre requête, avec 25s pour la requête avec une fraction des données que j'ai. Je ne comprends pas comment ces deux select count(*) au début, devrait aider.
OriginalL'auteur John
Ou vous pouvez utiliser le rang comme ceci:
Et cela donnera juste un enregistrement pour chaque quartile:
EDIT:
Le sqlFiddle exemple (http://sqlfiddle.com/#!9/a14a4/17) ressemble à ça après c'est supprimée
Si je supprime le commentaire sur le code (/* */) en haut de la sqlfiddle exemple que vous donnez, ça marche pour moi.
OriginalL'auteur John
Voici une requête je suis venu pour le calcul des quartiles; il fonctionne dans ~0.04 s w/~5000 lignes de la table. J'ai inclus les valeurs min/max, comme je suis en fin de compte à l'aide de ces données pour construire les quatre quartile des plages:
Violon ici: http://sqlfiddle.com/#!9/58c0e2/1
Il y a certainement des problèmes de performances; j'aimerais, si quelqu'un a des commentaires sur la façon de l'améliorer.
Exemple de liste de données:
Exemple de requête de sortie:
OriginalL'auteur icats
- Je utiliser cette solution avec une fonction MYSQL :
x est le centile vous voulez
array_values votre group_concat valeurs de l'ordre et séparés par des ,
Exemple :
OriginalL'auteur dartaloufe