[SQL] Select un nbre max de données = selectionner une ligne sur n.

Select un nbre max de données = selectionner une ligne sur n. [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 18-11-2015 à 09:18:25    

Bonjour,  
 
Je débute avec mysql et je voulais savoir s'il existe un moyen relativement simple de ne sélectionner qu'un certain nombre de données (on va me dire LIMIT) linéairement réparties sur l'ensemble des données initialement sélectionnées.
 
C'est pour tracer des graphes. Initialement, je choisi deux dates et ça me renvoie l'ensemble des données. Sauf que si les dates sont très éloignées, je peux avoir des millions de données, j'aurai donc souhaité faire une LIMIT 500, mais pas à partir d'un côté ou l'autre des enregistrements, mais avec des points linéairement répartis.
 
Merci d'avance :jap:


Message édité par _pollux_ le 18-11-2015 à 09:57:02

---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 09:18:25   

Reply

Marsh Posté le 18-11-2015 à 09:50:59    

J'viens de regarder un exemple donné sur mon générateur de graph (highcharts.com en l'occurence).

 

https://github.com/highslide-softwa [...] om-sql.php

 

Ils trichent :/

 

Ils ont trois tables différentes qui reprennent les mêmes points qu'ils interrogent  en fonction de la période choisie :o


Message édité par _pollux_ le 18-11-2015 à 09:51:17

---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 11:24:41    

Tu pourrais donner un ex : c'est pas très clair, là :/
Commence par être très précis sur la formulation de tes critères de sélections des données. En général, quand on est capable de verbaliser ces critères de manière claire, on trouve soi-même la réponse à son pb ;)
 
Je peux juste te proposer l'algo suivant par rapport à ce que j'ai compris. Tu veux avoir au max 500 valeurs à afficher. Je pars du pré-requis que chaque enregistrement à un ID, entier, qui va de 1 à n et qu'il n'y a pas de trous :
1) sélectionner les ID correspondant aux critères de sélection des valeurs entre 2 dates
2) NbValsTrouvées = COUNT(enregistrements trouvés)
3) NbValARecupérer = min(500, NbValsTrouvées)
4) Pas = floor(NbValsTrouvées / NbValARecupérer)
5) à partir du premier ID trouvé, générer les suivants espace du Pas calculé (ex : si ID = 301 et Pas = 10, alors les ID suivants sont 311, 321...)
6) faire une requête SQL avec dans WHERE ID IN (liste des ID générés).
 
C'est bourrin mais ça devrait marcher.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-11-2015 à 12:16:13    

Hum, je vais essayer d'être plus clair.
 

|   Date      |   Valeur  |
---------------------------
|       1     |     12    |
|       2     |     15    |
|       3     |     34    |
|      ...    |    ....   |
|     15000   |   135480  |
|     15001   |   135493  |
|     ...     |    ...    |


Seule nuance, mes dates sont en réalité des datetime.
Mon but, c'est de tracer le graphe Valeur = f( Date).
Dans la réalité, je peux avoir largement plus de 15000 valeurs (disons des millions). C'est très lent à tracer.  
Or, un graphe avec par exemple 500 points suffirait largement.
 
Donc, si par exemple, je veux tracer quelque chose de cohérent entre deux dates, il faut que je ne garde que une ligne sur n. Avec une répartition équilibrée, pas aléatoire.
 
Je sais pas si c'est plus clair.


---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 12:18:13    

Je viens de regarder ce que tu me proposes. La solution est intéressante mais je n'ai pas d'ID initialement. Bon, si il le faut, je peux en rajouter un.


---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 14:14:59    

Ca veut dire quoi, une représentation équilibrée :??: Qui suit une loi Gaussienne ?
 
Concrètement, si pour un même datetime ou alors des datetimes très proches, t'as des valeurs de ce genre : 10, 150, 3, 50, 300, 27, 12... Tu veux que ce soit quelle valeur qui soit sélectionnée :??:
 
T'as peut-être une préparation des données à faire au préalable et pas travailler directement sur les données brutes. Est-ce que faire une moyenne (ou min, ou max) pour des dateimes identiques ou proches afin d'avoir qu'une valeur en sortie aurait du sens ?
 
Sinon, faut vraiment que tu indiques les critères de sélection pour avoir "une répartition équilibrée" :o
 
dit : mon algo, en un sens, donne une répartition aléatoire puisqu'il travaille sur la valeur des ID, donc indépendamment des valeurs associées aux ID.

Message cité 1 fois
Message édité par rufo le 18-11-2015 à 14:16:14

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-11-2015 à 14:21:15    

rufo a écrit :

1 Ca veut dire quoi, une représentation équilibrée :??: Qui suit une loi Gaussienne ?

 

2 Concrètement, si pour un même datetime ou alors des datetimes très proches, t'as des valeurs de ce genre : 10, 150, 3, 50, 300, 27, 12... Tu veux que ce soit quelle valeur qui soit sélectionnée :??:

 

T'as peut-être une préparation des données à faire au préalable et pas travailler directement sur les données brutes. Est-ce que faire une moyenne (ou min, ou max) pour des dateimes identiques ou proches afin d'avoir qu'une valeur en sortie aurait du sens ?

 

Sinon, faut vraiment que tu indiques les critères de sélection pour avoir "une répartition équilibrée" :o

 

dit : mon algo, en un sens, donne une répartition aléatoire puisqu'il travaille sur la valeur des ID, donc indépendamment des valeurs associées aux ID.


1. Dans le sens ou

Code :
  1. SELECT * FROM table ORDER BY RAND() LIMIT 500

n'est pas forcément une bonne idée.

 

2. Il faut que ce soit également réparti en fonction des temps, peu importe les valeurs. Par exemple, si je dois prendre une valeur sur 3 pour être au final à moins de 500 points, il me faut les temps 1, 4, 7, etc ...

 

Très franchement, ton algo présenté semble bon. J'espérais juste pouvoir me passer d'une colonne ID et avoir une commande plus directe en SQL.


Message édité par _pollux_ le 18-11-2015 à 14:28:13

---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 15:00:12    

Un premier élagage sinon :
SELECT champdatetime, valeur FROM (SELECT champdatetime, valeur, RAND() AS cID FROM matable ORDER BY champdatetime, cID) AS Tmp GROUP BY champdatetime LIMIT 500


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-11-2015 à 16:13:05    

Merci, je vais essayer ça dès que possible :jap:


---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Marsh Posté le 18-11-2015 à 16:30:00    

Rassurez moi, quand vous parlez d'ID, vous voulez bien dire un champ indépendant de la clé primaire et dont l'application qui alimente la DB assure l'ordre et la contiguité ?

Reply

Marsh Posté le 18-11-2015 à 16:30:00   

Reply

Marsh Posté le 18-11-2015 à 16:47:00    

Non, je parlais d'un champ auto incrémenté. Mais c'est vrai qu'on peut se passer de l'ID auto-incrémenté avec cette astuce :
SET @pos=0;
SELECT champdatetime, valeur, (@pos:=@pos+1) AS Rang FROM matable WHERE...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-11-2015 à 17:35:17    

ça fait beaucoup pour un débutant d'un seul coup :D  
 
Mais je vais regarder ça aussi :o


---------------
Le topic du sport électronique@hfr : watch the l33t !
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed