Vă mulțumim pentru susținere

Distribuția mesei în timp

Am un tabel MySQL cu aproximativ 3000 de rânduri pe utilizator. Una dintre coloane este un câmp datetime, care este mutabil, deci rândurile nu sunt în ordine cronologică.

Aș dori să vizualizez distribuția de timp într-o diagramă, așa că am nevoie de un număr de puncte de date individuale. 20 de date ar fi de ajuns.

Am putea face acest lucru:

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

și priviți la fiecare rândul al 150-lea.

Sau aș putea să fac 20 de interogări separate și să folosesc limit 1 și offset .

Dar trebuie să existe o soluție mai eficientă ...

0
adăugat editat
Vizualizări: 1
puteți descrie întrebarea un pic mai mult? Care este rezultatul pe care îl cauți? Doriți să vedeți o diagramă de frecvență (de exemplu: numărul de intrări în Jan = 132, Feb = 112, Mar = 173 etc.) sau doriți valorile individuale ale celei mai vechi intrări, cea mai veche intrare 150, etc?
adăugat autor nickf

7 răspunsuri

Pentru referința mea - și pentru cei care utilizează postgres - Postgres 9.4 va fi comandat seturi de agregate care ar trebui să rezolve această problemă:

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/

0
adăugat

@Michal

Din orice motiv, exemplul dvs. funcționează numai în cazul în care @recnum utilizează un operator mai puțin decât un operator. Cred că atunci când locul unde filtrează un rând, rownum-ul nu crește și nu se poate potrivi cu altceva.

Dacă tabela originală are o coloană ID incrementată automat și rândurile au fost inserate în ordine cronologică, atunci ar trebui să funcționeze:

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

Bineînțeles că nu funcționează dacă nu există o corelație între id și intervalul de timp, cu excepția cazului în care nu vă interesează de fapt obținerea unor câmpuri de timp uniforme, doar 20 aleatoare.

0
adăugat

Ceva de genul asta mi-a venit în minte

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

Nu am MySQL la mână, dar poate că asta îți va ajuta ...

0
adăugat

În ceea ce privește vizualizarea, știu că nu e vorba de eșantionarea periodică despre care vorbești, dar aș uita la toate rândurile pentru un utilizator și aleg o gaură de interval, SUM în galeți și arăta pe un grafar sau ceva asemănător. Aceasta ar arăta o "distribuție" reală, deoarece multe evenimente în cadrul unui interval de timp pot fi semnificative.

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)

Sau dacă nu vă place modul în care trebuie să vă repetați - sau dacă jucați cu diferite găleți și doriți să analizați pe mai mulți utilizatori în 3-D (măsurați în Z contra x, y uid, găleată):

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

Dacă am vrut să complot în 3-D, probabil aș determina o modalitate de a comanda utilizatorii în funcție de o anumită valoare globală semnificativă pentru utilizator.

0
adăugat
Nu, totuși, optimizatorul nu re-calculează aceste expresii, deoarece știe că funcțiile sunt deterministe.
adăugat autor Cade Roux
poți să faci "GRUPUL CU ORGANUL DE VĂCHĂTOARE CU GRUP"? care pare ca ar fi mult mai eficient (nu trebuie sa recalculati acea coloana de fiecare data)
adăugat autor nickf

Michal Sznajder a avut aproape acest lucru, dar nu puteți folosi aliasuri de coloane într-o clauză WHERE din SQL. Deci trebuie să-l înfășurați ca o masă derivată. Am incercat si am intors 20 randuri:

SELECT * FROM (
    SELECT @rownum:[email protected]+1 AS rownum, e.*
    FROM (SELECT @rownum := 0) r, entries e) AS e2
WHERE uid = ? AND rownum % 150 = 0;
0
adăugat
select timefield
from entries
where rand() = .01 --will return 1% of rows adjust as needed.

Nu este un expert mysql, deci nu sunt sigur cum rand() funcționează în acest mediu.

0
adăugat
care ar trebui să fie "rand() <.01"
adăugat autor nickf

Îți pasă de punctele de date individuale? Sau va folosi funcțiile agregate statistice pe numărul de zi suficient pentru a vă spune ce vreți să știți?

0
adăugat