Question

J'ai une table MySQL avec environ 3 000 lignes par utilisateur.L'une des colonnes est un champ datetime, qui est modifiable, donc les lignes ne sont pas classées par ordre chronologique.

J'aimerais visualiser la distribution temporelle dans un graphique, j'ai donc besoin d'un certain nombre de points de données individuels.20 points de données suffiraient.

Je pourrais faire ceci :

select timefield from entries where uid = ? order by timefield;

et regardez toutes les 150ème lignes.

Ou je pourrais faire 20 requêtes distinctes et utiliser limit 1 et offset.

Mais il doit y avoir une solution plus efficace...

Était-ce utile?

La solution

Michal Sznajder l'a presque eu, mais vous ne pouvez pas utiliser d'alias de colonne dans une clause WHERE en SQL.Vous devez donc l'envelopper sous forme de table dérivée.J'ai essayé ceci et cela renvoie 20 lignes :

SELECT * FROM (
    SELECT @rownum:=@rownum+1 AS rownum, e.*
    FROM (SELECT @rownum := 0) r, entries e) AS e2
WHERE uid = ? AND rownum % 150 = 0;

Autres conseils

Quelque chose comme ça m'est venu à l'esprit

select @rownum:=@rownum+1 rownum, entries.* 
from (select @rownum:=0) r, entries 
where uid = ? and rownum % 150 = 0

Je n'ai pas MySQL sous la main mais peut-être que cela aidera...

En ce qui concerne la visualisation, je sais que ce n'est pas l'échantillonnage périodique dont vous parlez, mais je regarderais toutes les lignes d'un utilisateur et choisirais un compartiment d'intervalle, SOMME dans les compartiments et afficherais sur un graphique à barres ou similaire.Cela montrerait une véritable « distribution », puisque de nombreuses occurrences au cours d’une période donnée peuvent être significatives.

SELECT DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket -- choose an appropriate granularity (days used here)
     ,COUNT(*)
FROM entries
WHERE uid = ?
GROUP BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)
ORDER BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)

Ou si vous n'aimez pas la façon dont vous devez vous répéter - ou si vous jouez avec différents compartiments et souhaitez analyser de nombreux utilisateurs en 3D (mesurez en Z par rapport à x, y uid, bucket) :

SELECT uid
    ,bucket
    ,COUNT(*) AS measure
FROM (
    SELECT uid
        ,DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket
    FROM entries
) AS buckets
GROUP BY uid
    ,bucket
ORDER BY uid
    ,bucket

Si je voulais tracer en 3D, je déterminerais probablement un moyen de classer les utilisateurs en fonction d'une métrique globale significative pour l'utilisateur.

@Michal

Pour une raison quelconque, votre exemple ne fonctionne que lorsque le Where @recnum utilise un opérateur inférieur à.Je pense que lorsque le filtre Where filtre une ligne, le numéro de ligne n'est pas incrémenté et il ne peut correspondre à rien d'autre.

Si la table d'origine a une colonne d'identifiant incrémentée automatiquement et que les lignes ont été insérées par ordre chronologique, cela devrait fonctionner :

select timefield from entries
where uid = ? and id % 150 = 0 order by timefield;

Bien sûr, cela ne fonctionne pas s'il n'y a pas de corrélation entre l'identifiant et le champ temporel, à moins que vous ne vous souciez pas réellement d'obtenir des champs temporels régulièrement espacés, seulement 20 champs aléatoires.

Vous souciez-vous vraiment des points de données individuels ?Ou est-ce que l'utilisation des fonctions d'agrégation statistique sur le numéro du jour suffira à vous dire ce que vous souhaitez savoir ?

select timefield
from entries
where rand() = .01 --will return 1% of rows adjust as needed.

Je ne suis pas un expert MySQL, donc je ne suis pas sûr de savoir comment rand() fonctionne dans cet environnement.

Pour ma référence - et pour ceux qui utilisent Postgres - Postgres 9.4 aura ordonné des agrégats définis qui devraient résoudre ce problème :

SELECT percentile_disc(0.95) 
WITHIN GROUP (ORDER BY response_time) 
FROM pageviews;

Source: http://www.craigkerstiens.com/2014/02/02/Examining-PostgreSQL-9.4/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top