2011-01-19 19 views
6

tengo una tabla de datos que deseo seleccionar a través de un proceso almacenado para que los usuarios puedan conectar una interfaz MS Excel y usar los datos sin procesar como fuente para graficargenerar tabla temporal sql de fechas secuenciales a la combinación externa izquierda a

El problema con los datos brutos de la tabla es que existen vacíos en las fechas porque si no hay datos para un día determinado (no hay registros con esa fecha), cuando los usuarios intentan graficar esto crea problemas.

También quiero actualizar mi proceso almacenado a la combinación externa izquierda a una tabla temporal de fechas para que el lado derecho aparezca como nulos que puedo convertir a cero para que tengan una experiencia de trazado simple.

¿cómo puedo generar la tabla de fechas de un campo entre una fecha de inicio y una de finalización?

+0

Usted está buscando un generador de secuencias; [este] (http://msdn.microsoft.com/en-us/library/aa175802 (v = sql.80) .aspx) era el artículo que solía basar en la mía la última vez que lo necesitaba. Aunque, por supuesto, si solo quieres hacerlo una vez, un cursor o un simple loop funcionarían bien ... –

Respuesta

12

En SQL Server 2005 en adelante, se puede usar algo como esto (una expresión de tabla común CTE) para hacer esto:

DECLARE @DateFrom DATETIME 
SET @DateFrom = '2011-01-01' 

DECLARE @DateTo DATETIME 
SET @DateTo = '2011-01-10' 

;WITH DateRanges AS 
(
    SELECT @DateFrom AS 'DateValue' 
    UNION ALL 
    SELECT DATEADD(DAY, 1, DateValue) 
    FROM DateRanges 
    WHERE DateValue < @DateTo 
) 
SELECT * FROM DateRanges 

Se podría LEFT OUTER JOIN este CTE en contra de su mesa y devolver el resultado.

+0

¡Finalmente! Gracias por esto. Parecía que debería ser tan simple y, sin embargo, todas las otras respuestas a preguntas muy similares involucraban la creación de funciones o tablas permanentes. Esta es exactamente la solución que necesitaba y funciona perfectamente. –

+0

Es la manera más fácil, pero si crece a miles o millones de fechas, tiene un rendimiento pobre en comparación con una tabla temporal o permanente. Mira esto: http://www.sqlservercentral.com/articles/T-SQL/74118/ –

4

Una forma sería con un CTE:

with cte_dates as (
    select cast('20110119' as datetime) as [date] 
    union all 
    select dateadd(dd, 1, [date]) 
     from cte_dates 
     where dateadd(dd, 1, [date]) <= '20111231' 
) 
select [date], YourColumn 
    from cte_dates 
     left join YourTable 
      on ... 
option (maxrecursion 0); 
+0

+1 porque tu publicación fue enviada en el minuto exacto de la respuesta aceptada, y porque tu cláusula WHERE es más sólida que la suya (funciona para intervalos mayores a 1, lo que se pasa por alto en la respuesta aceptada). – kmote

4

Otra forma de hacerlo es con una tabla de memoria. No se ahogará debido a limitaciones de recursión como algunas de las soluciones anteriores.

DECLARE @dates AS TABLE ([Date] date); 

DECLARE @date date = {d '2010-10-01'}; 
DECLARE @endDate date = {d '2010-11-01'}; 

while (@date < @endDate) 
BEGIN 
    INSERT INTO @dates VALUES (@date); 
    SET @date = dateadd(DAY, 1, @date) 
END 
SELECT * FROM @dates; 

SQL Fiddle

+0

Utilice esta solución si obtiene "Se ha agotado la recursividad máxima". – Diego

Cuestiones relacionadas