Simular la function de retardo en MySQL

| time | company | quote | +---------------------+---------+-------+ | 0000-00-00 00:00:00 | GOOGLE | 40 | | 2012-07-02 21:28:05 | GOOGLE | 60 | | 2012-07-02 21:28:51 | SAP | 60 | | 2012-07-02 21:29:05 | SAP | 20 | 

¿Cómo hago un retraso en esta tabla en MySQL para imprimir la diferencia entre comillas, por ejemplo:

 GOOGLE | 20 SAP | 40 

    Este es mi truco MySQL favorito.

    Así es como se emula la function de retraso:

     SET @quot=-1; select time,company,@quot lag_quote, @quot:=quote curr_quote from stocks order by company,time; 
    • lag_quote contiene el valor de la cita de la fila anterior. Para la primera fila @quot es -1.
    • curr_quote contiene el valor de la cita de la fila actual.

    Notas:

    1. order by cláusula es importante aquí al igual que en una function de window normal.
    2. También es posible que desee utilizar lag para la company solo para asegurarse de que está calculando la diferencia en las cotizaciones de la misma company .
    3. También puede implementar contadores de fila de la misma manera @cnt:=@cnt+1

    Lo bueno de este esquema es que es computacionalmente muy delgado en comparación con algunos otros enfoques, como el uso de funciones agregadas, procedimientos almacenados o procesamiento de datos en el server de aplicaciones.

    EDITAR:

    Ahora viene su pregunta de get el resultado en el formatting que mencionó:

     SET @quot=0,@latest=0,company=''; select B.* from ( select A.time,A.change,IF(@comp<>A.company,1,0) as LATEST,@comp:=A.company as company from ( select time,company,quote-@quot as change, @quot:=quote curr_quote from stocks order by company,time) A order by company,time desc) B where B.LATEST=1; 

    La anidación no está relacionada, por lo que no es tan mala (computacionalmente) como parece (sintácticamente) 🙂

    Avíseme si necesita ayuda con esto.

    Para lograr el resultado deseado, primero debe encontrar la última y la próxima timestamp para cada compañía. Es bastante simple con la siguiente consulta:

     SELECT c.company, c.mts, max(l.ts) AS lts FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c LEFT JOIN cq l ON c.company = l.company AND c.mts > l.ts GROUP BY c.company, c.mts; 

    Ahora debe join a esta subconsulta con la tabla original para get los resultados deseados:

     SELECT c.company, l.quote, coalesce(l1.quote, 0), (l.quote - coalesce(l1.quote, 0)) AS result FROM (SELECT c.company, c.mts, max(l.ts) AS lts FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c LEFT JOIN cq l ON c.company = l.company AND c.mts > l.ts GROUP BY c.company, c.mts) AS c LEFT JOIN cq AS l ON l.company = c.company AND l.ts = c.mts LEFT JOIN cq AS l1 ON l1.company = c.company AND l1.ts = c.lts; 

    Puede observar los resultados en SQL Fiddle .

    Esta consulta usa solo capacidades estándar de SQL y debería funcionar en cualquier RDBMS.