Que fuerte -> NPI

14/10/2007 - 16:09 por David | Informe spam
Microsoft SQL Server 2000

Muy buenas, partiendo de una tabla con la siguiente definición
(SIMPLIFICADA)

Tabla_Periodos:
-

inicio (datetime)
fin (datetime)
nombre (varchar[4])


Los periodos (inicio - fin) pueden coindicir TOTALMENTE (ser idénticos)
Los periodos (inicio - fin) pueden coindicir PARCIALMENTE (coindicir en
algún/as fecha/s)
Los periodos (inicio - fin) puden ser disjuntos (no coincidir en ninguna
fecha)

Ejemplo de los datos

17/10/2005 31/10/2005 OCT
26/10/2005 31/12/2005 TG
01/11/2005 30/11/2005 TG
02/11/2005 31/12/2005 TG
02/11/2005 11/04/2006 TG
02/11/2005 11/04/2006 TG
03/11/2005 11/04/2006 TG
24/06/2006 21/07/2006 TG
31/12/2005 31/12/2005 NV
12/04/2005 15/04/2005 ABR
12/04/2006 15/04/2006 TG
22/07/2006 26/08/2006 TG
27/08/2006 15/09/2006 TG
16/09/2006 01/10/2006 TG
01/01/2006 11/04/2006 OF
12/04/2006 15/04/2006 OF
16/04/2006 23/06/2006 TG
16/06/2006 15/07/2006 OF
16/07/2006 31/07/2006 OF
01/09/2006 15/09/2006 OF
16/09/2006 30/12/2006 OF
11/02/2006 11/02/2006 11F
18/02/2006 18/02/2006 TG
25/02/2006 25/02/2006 TG
12/04/2006 16/04/2006 SS
17/04/2006 30/04/2006 TG
24/12/2005 24/12/2005 NB
31/12/2005 31/12/2005 NV
08/11/2005 31/12/2005 TG
11/02/2006 11/02/2006 SV
18/02/2006 18/02/2006 TG
25/02/2006 25/02/2006 TG

¿Es posible escribir una consulta que devuelva las tuplas que cumplan las
siguientes restricciones?

En cuanto compartan un MISERABLE día en el periodo (por supuesto más días o
incluso todo el periodo) Y EL NOMBRE ES EL MISMO

Yo no sé por dónde empezar, de antemano gracias
 

Leer las respuestas

#1 Alejandro Mesa
14/10/2007 - 17:57 | Informe spam
Hola David,

1 - Una fila siempre cumplira la condicion consigo misma, por lo que
necesitamos una clave primaria o restriccion de unicidad para poder excluir
la relacion de una fila consigo misma. Supongamos que la tabla tiene una
columna [id] con propiedad IDENTITY, entonces pudieramos usar:

select
*
from
dbo.periodos as a
inner join
dbo.periodos as b
on a.[id] != b.[id]
and a.nombre = b.nombre
and a.inicio <= b.fin
and a.fin >= b.inicio

Un pequeño problema con esta solución, es que si dos filas machan, entonces
el par sera seleccionado dos veces (a, b) y (b, a), porque la relacion es
bidireccional. Por ejemplo, las filas 2 y 3 machan, asi que tendremos el sgte
resultado con la sentencia anterior:

3 2005-11-01 00:00:00.000 2005-11-30 00:00:00.000 TG 2 2005-10-26
00:00:00.000 2005-12-31 00:00:00.000 TG

2 2005-10-26 00:00:00.000 2005-12-31 00:00:00.000 TG 3 2005-11-01
00:00:00.000 2005-11-30 00:00:00.000 TG

Te das cuenta de lo que quiero decir, debemos de seleccionar el par una sola
vez. Que pasa si ejecutamos esta sentencia:

SELECT DISTINCT
CASE WHEN a.[id] < b.[id] THEN a.[id] ELSE b.[id] END p1_id,
CASE WHEN b.[id] >= a.[id] THEN b.[id] ELSE a.[id] END p2_id
FROM
dbo.[periodos] AS a
INNER JOIN
dbo.[periodos] AS b
ON a.[id] != b.[id]
AND a.nombre = b.nombre
AND a.inicio <= b.fin
AND a.fin >= b.inicio
GO

Entonces el par (2, 3) y (3, 2) sera seleccionado solo una vez, por lo que
si usamos:

SELECT
p1.*,
p2.*
FROM
dbo.[periodos] AS p1
INNER JOIN
(
SELECT DISTINCT
CASE WHEN a.[id] < b.[id] THEN a.[id] ELSE b.[id] END p1_id,
CASE WHEN b.[id] >= a.[id] THEN b.[id] ELSE a.[id] END p2_id
FROM
dbo.[periodos] AS a
INNER JOIN
dbo.[periodos] AS b
ON a.[id] != b.[id]
AND a.nombre = b.nombre
AND a.inicio <= b.fin
AND a.fin >= b.inicio
) AS m
ON p1.[id] = m.p1_id
INNER JOIN
dbo.[periodos] AS p2
ON m.p2_id = p2.[id]
ORDER BY
p1.[id],
p2.[id]
GO

Tendriamos el resultado de todos los pares que cumplen la condicion.


AMB

"David" wrote:

Microsoft SQL Server 2000

Muy buenas, partiendo de una tabla con la siguiente definición
(SIMPLIFICADA)

Tabla_Periodos:
-

inicio (datetime)
fin (datetime)
nombre (varchar[4])


Los periodos (inicio - fin) pueden coindicir TOTALMENTE (ser idénticos)
Los periodos (inicio - fin) pueden coindicir PARCIALMENTE (coindicir en
algún/as fecha/s)
Los periodos (inicio - fin) puden ser disjuntos (no coincidir en ninguna
fecha)

Ejemplo de los datos

17/10/2005 31/10/2005 OCT
26/10/2005 31/12/2005 TG
01/11/2005 30/11/2005 TG
02/11/2005 31/12/2005 TG
02/11/2005 11/04/2006 TG
02/11/2005 11/04/2006 TG
03/11/2005 11/04/2006 TG
24/06/2006 21/07/2006 TG
31/12/2005 31/12/2005 NV
12/04/2005 15/04/2005 ABR
12/04/2006 15/04/2006 TG
22/07/2006 26/08/2006 TG
27/08/2006 15/09/2006 TG
16/09/2006 01/10/2006 TG
01/01/2006 11/04/2006 OF
12/04/2006 15/04/2006 OF
16/04/2006 23/06/2006 TG
16/06/2006 15/07/2006 OF
16/07/2006 31/07/2006 OF
01/09/2006 15/09/2006 OF
16/09/2006 30/12/2006 OF
11/02/2006 11/02/2006 11F
18/02/2006 18/02/2006 TG
25/02/2006 25/02/2006 TG
12/04/2006 16/04/2006 SS
17/04/2006 30/04/2006 TG
24/12/2005 24/12/2005 NB
31/12/2005 31/12/2005 NV
08/11/2005 31/12/2005 TG
11/02/2006 11/02/2006 SV
18/02/2006 18/02/2006 TG
25/02/2006 25/02/2006 TG

¿Es posible escribir una consulta que devuelva las tuplas que cumplan las
siguientes restricciones?

En cuanto compartan un MISERABLE día en el periodo (por supuesto más días o
incluso todo el periodo) Y EL NOMBRE ES EL MISMO

Yo no sé por dónde empezar, de antemano gracias






Preguntas similares