SQL - Consulta tremendamente dificil (para mi)

 
Vista:

Consulta tremendamente dificil (para mi)

Publicado por Oscar (39 intervenciones) el 17/02/2012 21:33:09
Hola
Un favor urgente.. necesito hacer una consulta con sql normal con lo siguiente:
Tengo una tabla con muchas fechas
Reg Fecha
1 01/01/2010
2 02/01/2010
3 03/01/2010
4 08/03/2010

Necesito que el resultado de la consulta me traiga los lapsos de tiempo mayores a un número específico ej: > 30 días, para el caso del ejemplo deberia traerme:

Reg1 Reg2 Fecha1 Fecha2 Número de dias
3 4 03/01/2010 08/03/2010 Fecha2-Fecha1

Está muy dificil verdad?
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta tremendamente dificil (para mi)

Publicado por leonardo_josue (1173 intervenciones) el 17/02/2012 22:06:24
Hola Oscar:

La dificultad de los problemas es proporcional al empeño que le pongas en tratar de resolverlos... por consiguiente creo que no te haz tomado el tiempo suficiente como para pensar en cómo resolverlo.

Si tienes tus registros numerados por fecha podrías hacer un LEFT JOIN con la misma tabla (utilizando dos alias, por ejemplo T1 y T2). En lugar de hacer ON T1.reg = T2.reg harías ON T1.reg = (T2.reg - 1). Con esto obtendrías algo como esto:

1
2
3
4
5
6
7
8
9
+------+------+------------+------------+------------+
| reg1 | reg2 | fecha1     | fecha2     | diferencia |
+------+------+------------+------------+------------+
|    1 |    2 | 01/01/2010 | 02/01/2010 |          1 |
|    2 |    3 | 02/01/2010 | 03/01/2010 |          1 |
|    3 |    4 | 03/01/2010 | 08/02/2010 |         36 |
|    4 | NULL | 08/02/2010 | NULL       |       NULL |
+------+------+------------+------------+------------+
4 rows in set (0.00 sec)


No mencionas qué manejador de BD estás utilizando, pero imagino que debe poseer alguna función predefinida para calcular la diferencia en días entre dos fechas, es cuestión que investigues cual es).

El último de los registros aparece como NULL pues no hay una fecha posterior. Lo único que faltaría es ordenar de manera descendente por el campo diferencia y traer sólo el primer registro. ¿Difícil?, ya vez que no... intenta hacerlo, y si continuas con problemas postea algo de lo que intentaste hacer y con gusto te ayudamos a afinar la consulta.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta tremendamente dificil (para mi)

Publicado por leonardo_josue (1173 intervenciones) el 17/02/2012 22:10:22
EDITO: la ordenación descendente y obtener el primer registro sería válido para obtener la mayor diferencia. En tu caso, como quieres obtener aquellos periodos con diferencia mayor o a un numero dado simplemente tendrías que hacer

1
2
WHERE
diferencia > 30


donde 30 es el número de días que quiere evaluar

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Consulta tremendamente dificil (para mi)

Publicado por Oscar (39 intervenciones) el 17/02/2012 22:16:59
Jejeje gracias Leonardo, tendré en cuenta la idea y el consejo, pero es que la verdad no se me ocurría como empezar y necesitaba una pista. nuevamente muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Consulta tremendamente dificil (para mi)

Publicado por Oscar (39 intervenciones) el 21/02/2012 17:05:20
El campo reg1 no lo tengo como identificador, el campo reg existe varias veces con fechas diferentes, trato de hacer la consulta utilizando unicamente la fecha pero me salen muchos registros en t2.fecha2 NULL y por ende la diferencia me da NULL

SELECT A.FECHANOVEDAD, B.FECHANOVEDAD,DATEDIFF(DD,A.FECHANOVEDAD,B.FECHANOVEDAD)
FROM TABLA A LEFT OUTER JOIN TABLA B
ON A.FECHANOVEDAD=DATEADD(DD,1,B.FECHANOVEDAD)
WHERE DATEDIFF(DD,A.FECHANOVEDAD,B.FECHANOVEDAD) > 30

Lo que necesito basicamente es encontrar en una tabla de auditoria (sin campos autonumericos) espacios significativos entre fechas, no es lógico que en una tabla de auditoria que debe registrar transacciones diarias hayan espacios de fechas mayores a 8, 15, 30 días.
Gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta tremendamente dificil (para mi)

Publicado por leonardo_josue (1173 intervenciones) el 21/02/2012 18:58:56
Hola de nuevo Oscar.

Si no tienes un campo consecutivo o autonumérico PUEDES CREARLO. En tu post no mencionas qué BD estás utilizando, pero puedo suponer que se trata de SQL Server, por lo tanto, puedes utilizar la función ROW_NUMBER para generar una columna que te enumere los registros por fecha:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
DECLARE @tabla table (fecha datetime)
INSERT INTO @tabla VALUES ('2010-01-01')
INSERT INTO @tabla VALUES ('2010-01-02')
INSERT INTO @tabla VALUES ('2010-01-10')
INSERT INTO @tabla VALUES ('2010-03-05')
 
select fecha from @tabla
/*
fecha
-----------------------
2010-01-01 00:00:00.000
2010-01-02 00:00:00.000
2010-01-10 00:00:00.000
2010-03-05 00:00:00.000
*/
 
select row_number() OVER(order by fecha) id, fecha from @tabla
/*
id                   fecha
-------------------- -----------------------
1                    2010-01-01 00:00:00.000
2                    2010-01-02 00:00:00.000
3                    2010-01-10 00:00:00.000
4                    2010-03-05 00:00:00.000
*/



Una vez que tengas esta nueva columna procederías como te propuse en el post anterior.

Ahora bien si esto te parece "complicado" hay otras formas de llegar al mismo resultado, otra opción sería haciendo subconsultas, es decir algo como esto:

1
2
3
4
seleccionar T1.fecha,
(seleccionar la mínima fecha
de la tabla T2
donde T2.fecha sea mayor a la T1.fecha) de la tabla T1


Lo único que tendrías que hacer es traducir esto a SQL.

Saludos
Leo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Consulta tremendamente dificil (para mi)

Publicado por Oscar (39 intervenciones) el 21/02/2012 20:23:25
perfecto gracias, trabajaré en la 2a opción teniendo en cuenta que los accesos que tengo son solo de consulta y no puedo crear tablas, ni campos, ni nada... estoy haciendo un trabajo de auditoria sobre unas tablas específicas.
la consulta me quedó de la siguiente forma, la mandé a ejecutar y esperaré los resultados ya que es un poco demorada por la cantidad de registros:

SELECT A.FECHANOVEDAD, (SELECT MIN(B.FECHANOVEDAD) FROM AUD B WHERE B.FECHANOVEDAD > A.FECHANOVEDAD) AS FECHANOVEDAD2
FROM AUD A

La sentencia me la soportó Sybase, vamos a ver que resultado me trae.
Nuevamente, muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta tremendamente dificil (para mi)

Publicado por leonardo_josue (1173 intervenciones) el 22/02/2012 17:37:31
Mucho ojo Oscar, la columna id que se genera al utilizar la función ROW_NUMBER es "virtual" es decir, no se genera físicamente sobre las tablas que se están consultando por lo tanto no es necesario que tengas permisos de creación de objetos, con los permisos de consulta basta y sobra para poder ejecutar la consulta. Sigo pensando que esta es la manera más óptima de hacerlo, pues con subconsultas (como ya te habrás dado cuenta) se puede volver muy lenta, pues se ejecuta una subconsulta por cada registro... deberías tratar de implementarla, estoy seguro que obtendrás mejores tiempos de respuesta.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar