SQL para hacer cálculos sobre filas de la misma tabla

Hola,

tengo un problema con una base de datos.

Es una tabla (events) donde se almacenan alarmas. El instante en el que se genera la alarma y el instante en el que deja de estar activa.

Quiero que mi consulta saque la alarma, el instante de generación, y la DURACIÓN que dicha alarma está activa. Si "1" es activa y "0" es inactiva, tendré que calcular la diferencia de instantes entre dos filas de la misma tabla. Pero sólo entre el "0" inmediatamente posterior a un "1", porque la alarma puede activarse y desactivarse muchas veces,

En MySQL uso lo siguiente

select
      alertas_UP.objectid,
        alertas_UP.clock,
      from_unixtime(alertas_UP.clock) as Fecha_Activacion,
      (alertas_DOWN.clock - alertas_UP.clock) as Duracion_Segs
      from alertas_UP left join
            (select * from
               events
                    where events.clock >= alertas_UP.clock
                    and and value=0
                    order by alertas_UP.clock desc
                    limit 1
            ) alertas_DOWN
      on alertas_UP.objectid = alertas_DOWN.objectid
      where alertas_UP.objectid = alertas_DOWN.objectid
      #and alertas_DOWN.clock >= alertas_UP.clock
        #and alertas_DOWN.eventid > alertas_UP.eventid
      order by alertas_UP.clock desc


La tabla alertas_UP es una que me he creado con las activaciones. alertas_DOWN es un alias.

MySQL me dice que:

Error Code: 1054. Unknown column 'alertas_UP.clock' in 'where clause'


No tengo ni idea de cuál es el error. Si alguien ve algo raro...

Saludos y gracias!
Sin ver los tipos de entidad que tienes con los atributos para ver si lo tienes bien puesto es un poco complicado, por lo menos para mi.
Pero te lo subo a ver si alguien si que sea capaz de verlo.
Mira si lo que falla es la negrita, supongo que el select interno no sabe qué es alertas_UP.

select
alertas_UP.objectid,
alertas_UP.clock,
from_unixtime(alertas_UP.clock) as Fecha_Activacion,
(alertas_DOWN.clock - alertas_UP.clock) as Duracion_Segs
from alertas_UP left join
(select * from
events
where events.clock >= alertas_UP.clock
and and value=0
order by alertas_UP.clock desc
limit 1
) alertas_DOWN
on alertas_UP.objectid = alertas_DOWN.objectid
where alertas_UP.objectid = alertas_DOWN.objectid
#and alertas_DOWN.clock >= alertas_UP.clock
#and alertas_DOWN.eventid > alertas_UP.eventid
order by alertas_UP.clock desc


Y ahora también veo que tienes dos ands seguidos.
bas escribió:Mira si lo que falla es la negrita, supongo que el select interno no sabe qué es alertas_UP.

select
alertas_UP.objectid,
alertas_UP.clock,
from_unixtime(alertas_UP.clock) as Fecha_Activacion,
(alertas_DOWN.clock - alertas_UP.clock) as Duracion_Segs
from alertas_UP left join
(select * from
events
where events.clock >= alertas_UP.clock
and and value=0
order by alertas_UP.clock desc
limit 1
) alertas_DOWN
on alertas_UP.objectid = alertas_DOWN.objectid
where alertas_UP.objectid = alertas_DOWN.objectid
#and alertas_DOWN.clock >= alertas_UP.clock
#and alertas_DOWN.eventid > alertas_UP.eventid
order by alertas_UP.clock desc


Y ahora también veo que tienes dos ands seguidos.

Con los and no deberia de tener problemas (los tiene comentados, pero aunque no los tuviera), solo esta diciendo que se tiene que cumplir todos los requisitos. Y alertas_UP si es donde le tira el error pero también lo usa antes y no le da error, a parte dice que ya lo creo.
El error puede que aunque te lo diga en el where venga de otro sitio.

Todo esto es mi opinion desde los pocos conocimientos que tengo de mysql.
bas escribió:Mira si lo que falla es la negrita, supongo que el select interno no sabe qué es alertas_UP.


Buenas. Eso es lo que he pensado. Pero no le veo sentido que no vea la tabla "alertas_UP". Ésa y "alertas_DOWN" son dos tablas creadas previamente a la consulta.

Lo del "and", efectivamente, están comentados.

Gracias a ambos!
@banderas20 @KePeRHeLL

Me sigue pareciendo un tema de scope. No asumiría que en cualquier caso todo va a ser visto por todo, el orden de ejecución puede variar según la estructura de la sentencia, ese inner join tiene pinta de ser evaluado antes que lo demás y ahí no existe alertas_UP. Haz alguna prueba rápida, mete alertas_UP en el from a ver cómo reacciona.

Con lo de los ands me refiero a esta línea:
and and value=0
bas escribió:@banderas20 @KePeRHeLL

Me sigue pareciendo un tema de scope. No asumiría que en cualquier caso todo va a ser visto por todo, el orden de ejecución puede variar según la estructura de la sentencia, ese inner join tiene pinta de ser evaluado antes que lo demás y ahí no existe alertas_UP. Haz alguna prueba rápida, mete alertas_UP en el from a ver cómo reacciona.

Con lo de los ands me refiero a esta línea:
and and value=0


El "and and" es un tema de copy paste para el foro. En el código real no está así.

Probaré lo que dices y te cuento.

Mil gracias! [oki]
Hay veces que hacer este tipo de funciones en una query es mas lento incluso que hacerlo con un pequeño script en python, php o cualquier lenguaje de programación.

Donde va a ir esa sentencia? A veces la solución mas simple es la mejor
alienvita2 escribió:
Donde va a ir esa sentencia? A veces la solución mas simple es la mejor


La idea es que corriera sobre la misma bbdd con un SP programado a horas determinadas con un trigger.

Probaré a usar variables en el SP a ver si con MySQL puro lo consigo. Si no, me apoyaré de Python o similar.

Gracias!
Hace un webo que no toco sentencias SQL, pero la sentencia donde lo tienes, así de primeras no tiene acceso a la tabla:

select * from
events
where events.clock >= alertas_UP.clock
and and value=0
order by alertas_UP.clock desc
limit 1


En este cacho código, no aparece por ninguna parte la tabla alertas_UP en la parte from; por eso te da el casque.
paper escribió:Hace un webo que no toco sentencias SQL, pero la sentencia donde lo tienes, así de primeras no tiene acceso a la tabla:

select * from
events
where events.clock >= alertas_UP.clock
and and value=0
order by alertas_UP.clock desc
limit 1


En este cacho código, no aparece por ninguna parte la tabla alertas_UP en la parte from; por eso te da el casque.


Esa tabla está creada antes de ese select. La he omitido aquí para no liar mucho.

¿Puede igualmente que no sepa verla?
Si, la creaste antes, pero no la has referenciado en el from, con lo que la clausula select no sabe ese objeto que es. Por eso te da el casque.
paper escribió:Si, la creaste antes, pero no la has referenciado en el from, con lo que la clausula select no sabe ese objeto que es. Por eso te da el casque.


¿Y cómo la referencio?

Gracias! :)
Si no me equivoco tienes que volverla a llamar en el from asignándole un alias y haces una consulta correlacionada.
KePeRHeLL escribió:Si no me equivoco tienes que volverla a llamar en el from asignándole un alias y haces una consulta correlacionada.


Me he perdido. ¿Me podrías poner un ejemplo?

Gracias!
Para referenciarla, debes de meterla en el from. El from de un sql es donde vas a ir a buscar los datos, si algo no está en el from, la consulta no sabe sacarla.
paper escribió:Para referenciarla, debes de meterla en el from. El from de un sql es donde vas a ir a buscar los datos, si algo no está en el from, la consulta no sabe sacarla.


Creo que ya está en el from, no?
No, no lo esta. Fijate:

select *
from events   <------- Solo esta Events
where events.clock >= alertas_UP.clock and and value=0
order by alertas_UP.clock desc
limit 1


Dependiendo la estructura de las tablas, deberías hacer un JOIN, usar un alias, o simplemente añadiendo la otra tabla en el FROM la consulta te funcionará, otra cosa los resultados que te dé:

select *
from events, alertas_UP
where events.clock >= alertas_UP.clock
and and value=0
order by alertas_UP.clock desc
limit 1
17 respuestas