Consulta

19/12/2008 - 11:00 por David | Informe spam
Muy buenas,

Microsoft SQL Server 2000

Escenario:
Tabla: [id],[desde],[hasta]

Campos [desde] y [hasta] almacenan fechas

¿Cómo montar una consulta que al pasarle un rango de fechas @inicio y @fin
devuelva los días que pertenencen al rango definido [desde] / [hasta]?

me explico:
en la tabla almaceno los siguientes rangos:

[desde] [hasta]
07/01/09 07/01/09
10/01/09 20/01/09


La consulta debería responder a la pregunta ¿Cuántos días "comparte" el
periodo por ejemplo del 06/01/09 al 12/01/09?

El resultado esperado:
1
3

el periodo introducido 06/01/09 al 12/01/09 para el primer registro comparte
1 día (el día 07/01/09)
el periodo introducido 06/01/09 al 12/01/09 para el segundo registro
comparten 3 días (el 10, 11 y el 12)

De antemano, muchísimas gracias.

Nota: ni idea por donde meterle mano.

Preguntas similare

Leer las respuestas

#1 Jose TH
19/12/2008 - 14:04 | Informe spam
Una idea ( si lo entendí bien):

Es como buscar la intersección de dos intervalos.

Ejemplo para un registro particular vas a encontrar la intersección entre el
intervalo de los parámetros, ejemplo @p1 y @p2 (primer intervalo) con el
intervalo de las columnas del registro, @f1 y @f2 (el segundo intervalo),
luego trata de implementar una formula:

1) Saca la fecha mínima entre @f2 y @p2 (los extremos derechos de cada
intervalo) (Case When...)
2) Saca la fecha máxima entre @f1 y @p1 (los extremos izquierdos de cada
intervalo) (Case.. When..)
3) Resta la fecha obtenida en (2) de la obtenida en (1) para calcular la
cantidad de dias (DateDiff) y sumale 1 dia.

DateDiff (day, MaximaFecha(@f1, @p1), MinimaFecha(@f2, @p2) + 1

4) Compara el resultado de (3) con Cero y devuelve el Maximo (para descartar
los negativos).

MaximoNumero(0, DateDiff (day, MaximaFecha(@f1, @p1),
MinimaFecha(@f2, @p2) + 1 )

Nota: esas funciones de Maximos y Minimos horizontales las puedes
implementar con Case, When.. preferible en udf's. Tambien quizas una udf
"DiasCompartidos" a la cual le mandes los 4 parametros:

select desde, hasta, dbo.DiasCompartidos(@p1, @p2, desde, hasta) as
DiasCompartidos
from tabla where

Si no es asi, pon mas ejemplos...



"David" escribió en el mensaje
news:
Muy buenas,

Microsoft SQL Server 2000

Escenario:
Tabla: [id],[desde],[hasta]

Campos [desde] y [hasta] almacenan fechas

¿Cómo montar una consulta que al pasarle un rango de fechas @inicio y @fin
devuelva los días que pertenencen al rango definido [desde] / [hasta]?

me explico:
en la tabla almaceno los siguientes rangos:

[desde] [hasta]
07/01/09 07/01/09
10/01/09 20/01/09


La consulta debería responder a la pregunta ¿Cuántos días "comparte" el
periodo por ejemplo del 06/01/09 al 12/01/09?

El resultado esperado:
1
3

el periodo introducido 06/01/09 al 12/01/09 para el primer registro
comparte 1 día (el día 07/01/09)
el periodo introducido 06/01/09 al 12/01/09 para el segundo registro
comparten 3 días (el 10, 11 y el 12)

De antemano, muchísimas gracias.

Nota: ni idea por donde meterle mano.


Respuesta Responder a este mensaje
#2 David
19/12/2008 - 23:06 | Informe spam
Efectivamente es el problema, voy a intentar implementar tu propuesta, ...
Respuesta Responder a este mensaje
#3 Alejandro Mesa
19/12/2008 - 23:36 | Informe spam
David,

Una forma seria usando una tabla calendario. Tabla que suele ser muy util
para muchos calculos con fecha.

La idea es expandir cada rango, incluyendo el que pasas como parametro, y
unir los resultados por dia, luego agrupar por [id].

CREATE FUNCTION dbo.ufn_Numbers(@max INT)
RETURNS TABLE
AS
RETURN (
WITH
L0 AS (SELECT 1 AS c1 UNION ALL SELECT 1),
L1 AS (SELECT 1 AS c1 FROM L0 AS a, L0 AS b),
L2 AS (SELECT 1 AS c1 FROM L1 AS a, L1 AS b),
L3 AS (SELECT 1 AS c1 FROM L2 AS a, L2 AS b),
L4 AS (SELECT 1 AS c1 FROM L3 AS a, L3 AS b),
L5 AS (SELECT 1 AS c1 FROM L4 AS a, L4 AS b)
SELECT TOP (@max) ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS Number
FROM L5
)
GO

CREATE TABLE #Calendar (
[dt] DATETIME NOT NULL UNIQUE CLUSTERED
)

INSERT INTO #Calendar([dt])
SELECT DATEADD(DAY, c.Number, '19000101')
FROM dbo.ufn_Numbers(365 * 200) AS c
GO

CREATE TABLE #t (
[id] INT NOT NULL IDENTITY UNIQUE,
desde DATETIME NOT NULL,
hasta DATETIME NOT NULL
)

set DATEFORMAT dmy

INSERT INTO #t VALUES('07/01/09', '07/01/09')
INSERT INTO #t VALUES('10/01/09', '20/01/09')

set DATEFORMAT mdy
GO

DECLARE @desde DATETIME, @hasta datetime

SET @desde = '20090106'
SET @hasta = '20090112'

;WITH r_set
AS
(
SELECT
a.[id]
FROM
#t AS a
INNER JOIN
#Calendar AS c
ON c.[dt] BETWEEN a.[desde] AND a.[hasta]
INNER JOIN
(SELECT @desde AS [desde], @hasta AS [hasta]) AS b
ON c.[dt] BETWEEN b.[desde] AND b.[hasta]
)
SELECT [id], COUNT(*) AS [cnt]
FROM r_set
GROUP BY [id]
ORDER BY [id]
GO

DROP FUNCTION [dbo].[ufn_Numbers]
GO

DROP TABLE #t, #Calendar
GO

Resultado:

id cnt
1 1
2 3


Why should I consider using an auxiliary calendar table?
http://sqlserver2000.databases.aspf...table.html


AMB



"David" wrote:

Muy buenas,

Microsoft SQL Server 2000

Escenario:
Tabla: [id],[desde],[hasta]

Campos [desde] y [hasta] almacenan fechas

¿Cómo montar una consulta que al pasarle un rango de fechas @inicio y @fin
devuelva los días que pertenencen al rango definido [desde] / [hasta]?

me explico:
en la tabla almaceno los siguientes rangos:

[desde] [hasta]
07/01/09 07/01/09
10/01/09 20/01/09


La consulta debería responder a la pregunta ¿Cuántos días "comparte" el
periodo por ejemplo del 06/01/09 al 12/01/09?

El resultado esperado:
1
3

el periodo introducido 06/01/09 al 12/01/09 para el primer registro comparte
1 día (el día 07/01/09)
el periodo introducido 06/01/09 al 12/01/09 para el segundo registro
comparten 3 días (el 10, 11 y el 12)

De antemano, muchísimas gracias.

Nota: ni idea por donde meterle mano.




Respuesta Responder a este mensaje
#4 Alejandro Mesa
19/12/2008 - 23:44 | Informe spam
Correción,

No es necesario usar la CTE.

SELECT
a.[id], COUNT(*) AS [cnt]
FROM
#t AS a
INNER JOIN
#Calendar AS c
ON c.[dt] BETWEEN a.[desde] AND a.[hasta]
INNER JOIN
(SELECT @desde AS [desde], @hasta AS [hasta]) AS b
ON c.[dt] BETWEEN b.[desde] AND b.[hasta]
GROUP BY
a.[id]
ORDER BY
a.[id]
GO


AMB



"Alejandro Mesa" wrote:

David,

Una forma seria usando una tabla calendario. Tabla que suele ser muy util
para muchos calculos con fecha.

La idea es expandir cada rango, incluyendo el que pasas como parametro, y
unir los resultados por dia, luego agrupar por [id].

CREATE FUNCTION dbo.ufn_Numbers(@max INT)
RETURNS TABLE
AS
RETURN (
WITH
L0 AS (SELECT 1 AS c1 UNION ALL SELECT 1),
L1 AS (SELECT 1 AS c1 FROM L0 AS a, L0 AS b),
L2 AS (SELECT 1 AS c1 FROM L1 AS a, L1 AS b),
L3 AS (SELECT 1 AS c1 FROM L2 AS a, L2 AS b),
L4 AS (SELECT 1 AS c1 FROM L3 AS a, L3 AS b),
L5 AS (SELECT 1 AS c1 FROM L4 AS a, L4 AS b)
SELECT TOP (@max) ROW_NUMBER() OVER(ORDER BY (SELECT 0)) AS Number
FROM L5
)
GO

CREATE TABLE #Calendar (
[dt] DATETIME NOT NULL UNIQUE CLUSTERED
)

INSERT INTO #Calendar([dt])
SELECT DATEADD(DAY, c.Number, '19000101')
FROM dbo.ufn_Numbers(365 * 200) AS c
GO

CREATE TABLE #t (
[id] INT NOT NULL IDENTITY UNIQUE,
desde DATETIME NOT NULL,
hasta DATETIME NOT NULL
)

set DATEFORMAT dmy

INSERT INTO #t VALUES('07/01/09', '07/01/09')
INSERT INTO #t VALUES('10/01/09', '20/01/09')

set DATEFORMAT mdy
GO

DECLARE @desde DATETIME, @hasta datetime

SET @desde = '20090106'
SET @hasta = '20090112'

;WITH r_set
AS
(
SELECT
a.[id]
FROM
#t AS a
INNER JOIN
#Calendar AS c
ON c.[dt] BETWEEN a.[desde] AND a.[hasta]
INNER JOIN
(SELECT @desde AS [desde], @hasta AS [hasta]) AS b
ON c.[dt] BETWEEN b.[desde] AND b.[hasta]
)
SELECT [id], COUNT(*) AS [cnt]
FROM r_set
GROUP BY [id]
ORDER BY [id]
GO

DROP FUNCTION [dbo].[ufn_Numbers]
GO

DROP TABLE #t, #Calendar
GO

Resultado:

id cnt
1 1
2 3


Why should I consider using an auxiliary calendar table?
http://sqlserver2000.databases.aspf...table.html


AMB



"David" wrote:

> Muy buenas,
>
> Microsoft SQL Server 2000
>
> Escenario:
> Tabla: [id],[desde],[hasta]
>
> Campos [desde] y [hasta] almacenan fechas
>
> ¿Cómo montar una consulta que al pasarle un rango de fechas @inicio y @fin
> devuelva los días que pertenencen al rango definido [desde] / [hasta]?
>
> me explico:
> en la tabla almaceno los siguientes rangos:
>
> [desde] [hasta]
> 07/01/09 07/01/09
> 10/01/09 20/01/09
>
>
> La consulta debería responder a la pregunta ¿Cuántos días "comparte" el
> periodo por ejemplo del 06/01/09 al 12/01/09?
>
> El resultado esperado:
> 1
> 3
>
> el periodo introducido 06/01/09 al 12/01/09 para el primer registro comparte
> 1 día (el día 07/01/09)
> el periodo introducido 06/01/09 al 12/01/09 para el segundo registro
> comparten 3 días (el 10, 11 y el 12)
>
> De antemano, muchísimas gracias.
>
> Nota: ni idea por donde meterle mano.
>
>
>
>
Respuesta Responder a este mensaje
#5 David
20/12/2008 - 00:15 | Informe spam
BUFFFFFFFFFFFFFFFFFFFFFFFFFFF !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

menos mal que interiormente me reconocía a mi mismo que sería IMPOSIBLE
resolver el problema, y me habeis demostrado que lamentablemente llevaba
razón.

Voy a intentar DIGERIR las propuestas.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida