sql - riñon - mesa mayo instrumental
Distribución de la mesa en el tiempo (7)
Algo como esto vino a mi mente
select @rownum:=@rownum+1 rownum, entries.*
from (select @rownum:=0) r, entries
where uid = ? and rownum % 150 = 0
No tengo MySQL en mi mano, pero quizás esto ayude ...
Tengo una tabla MySQL con aproximadamente 3000 filas por usuario. Una de las columnas es un campo de fecha y hora, que es mutable, por lo que las filas no están en orden cronológico.
Me gustaría visualizar la distribución del tiempo en un gráfico, por lo que necesito una cantidad de puntos de datos individuales. 20 puntos de datos serían suficientes.
Yo podría hacer esto:
select timefield from entries where uid = ? order by timefield;
y mira cada fila 150a.
O podría hacer 20 consultas por separado y usar el limit 1
y el offset
.
Pero debe haber una solución más eficiente ...
¿Realmente te importan los puntos de datos individuales? ¿O bastará con usar las funciones agregadas estadísticas en el número del día para decirle lo que desea saber?
select
timefield
from
entries
where
rand() = .01 --will return 1% of rows adjust as needed.
--No soy un experto en mysql, así que no estoy seguro de cómo funciona rand () en este entorno.
En cuanto a la visualización, sé que este no es el muestreo periódico del que hablas, pero miraría todas las filas de un usuario y elegiría un intervalo de cubos, SUM dentro de los cubos y se mostraría en un gráfico de barras o similar. Esto mostraría una "distribución" real, ya que muchas ocurrencias dentro de un marco de tiempo pueden ser significativas.
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)
O si no le gusta la manera en que tiene que repetirse, o si está jugando con diferentes cubos y desea analizar a través de muchos usuarios en 3-D (mida en Z contra x, uid, cubo):
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 quisiera trazar en 3-D, probablemente determine una forma de ordenar a los usuarios de acuerdo con alguna métrica general significativa para el usuario.
Michal Sznajder casi lo tenía, pero no se pueden usar alias de columna en una cláusula WHERE en SQL. Entonces debes envolverlo como una tabla derivada. Intenté esto y devuelve 20 filas:
SELECT * FROM (
SELECT @rownum:=@rownum+1 AS rownum, e.*
FROM (SELECT @rownum := 0) r, entries e) AS e2
WHERE uid = ? AND rownum % 150 = 0;
Para mi referencia, y para aquellos que usan postgres, Postgres 9.4 habrá ordenado conjuntos agregados que deberían resolver este problema:
SELECT percentile_disc(0.95) WITHIN GROUP (ORDER BY response_time) FROM pageviews;
Fuente: http://www.craigkerstiens.com/2014/02/02/Examining-PostgreSQL-9.4/
Por alguna razón, su ejemplo solo funciona cuando el @recnum donde usa un operador menor que. Creo que cuando el lugar filtra una fila, el Rownum no se incrementa, y no puede coincidir con nada más.
Si la tabla original tiene una columna de ID autoincrementado, y las filas se insertaron en orden cronológico, entonces esto debería funcionar:
select timefield from entries
where uid = ? and id % 150 = 0 order by timefield;
Por supuesto, eso no funciona si no hay una correlación entre el ID y el campo de tiempo, a menos que realmente no le interese obtener campos de tiempo espaciados uniformemente, solo 20 aleatorios.