rango por obtener filtrar fechas fecha entre ejemplo consultar consulta comparar sql mysql datetime between

por - obtener un rango de fechas en sql



generar días a partir del rango de fechas (23)

Me gustaría ejecutar una consulta como

select ... as days where `date` is between ''2010-01-20'' and ''2010-01-24''

Y devuelve datos como:

days ---------- 2010-01-20 2010-01-21 2010-01-22 2010-01-23 2010-01-24


Generar fechas entre dos campos de fecha

Si conoce la consulta SQL CTE, esta solución le ayudará a resolver su pregunta

Aquí hay un ejemplo

Tenemos fechas en una tabla

Nombre de la tabla: "testdate"

STARTDATE ENDDATE 10/24/2012 10/24/2012 10/27/2012 10/29/2012 10/30/2012 10/30/2012

Requiere resultado:

STARTDATE 10/24/2012 10/27/2012 10/28/2012 10/29/2012 10/30/2012

Solución:

WITH CTE AS (SELECT DISTINCT convert(varchar(10),StartTime, 101) AS StartTime, datediff(dd,StartTime, endTime) AS diff FROM dbo.testdate UNION ALL SELECT StartTime, diff - 1 AS diff FROM CTE WHERE diff<> 0) SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime FROM CTE

Explicación: explicación de consulta recursiva CTE

  • Primera parte de la consulta:

    SELECT DISTINCT convert(varchar(10), StartTime, 101) AS StartTime, datediff(dd, StartTime, endTime) AS diff FROM dbo.testdate

    Explicación: firstcolumn es "startdate", la segunda columna es la diferencia de fecha de inicio y finalización en días y se considerará como columna "diff"

  • Segunda parte de la consulta:

    UNION ALL SELECT StartTime, diff-1 AS diff FROM CTE WHERE diff<>0

    Explicación: Union all heredará el resultado de la consulta anterior hasta que el resultado sea nulo, por lo que el resultado "StartTime" heredará de la consulta CTE generada, y de diff, decrease - 1, por lo que se verá como 3, 2 y 1 hasta 0

Por ejemplo

STARTDATE DIFF 10/24/2012 0 10/27/2012 0 10/27/2012 1 10/27/2012 2 10/30/2012 0

Especificación del resultado

STARTDATE Specification 10/24/2012 --> From Record 1 10/27/2012 --> From Record 2 10/27/2012 --> From Record 2 10/27/2012 --> From Record 2 10/30/2012 --> From Record 3

  • Tercera parte de la consulta

    SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime FROM CTE

    Agregará el día "diff" en "startdate", por lo que el resultado debería ser el siguiente

Resultado

STARTDATE 10/24/2012 10/27/2012 10/28/2012 10/29/2012 10/30/2012


Aquí hay otra variación usando vistas:

CREATE VIEW digits AS SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9; CREATE VIEW numbers AS SELECT ones.digit + tens.digit * 10 + hundreds.digit * 100 + thousands.digit * 1000 AS number FROM digits as ones, digits as tens, digits as hundreds, digits as thousands; CREATE VIEW dates AS SELECT SUBDATE(CURRENT_DATE(), number) AS date FROM numbers;

Y luego puedes simplemente hacerlo (¿ves qué tan elegante es?):

SELECT date FROM dates WHERE date BETWEEN ''2010-01-20'' AND ''2010-01-24'' ORDER BY date

Actualizar

Vale la pena señalar que solo podrá generar fechas pasadas a partir de la fecha actual . Si desea generar cualquier tipo de intervalo de fechas (pasado, futuro y entre medio), tendrá que usar esta vista en su lugar:

CREATE VIEW dates AS SELECT SUBDATE(CURRENT_DATE(), number) AS date FROM numbers UNION ALL SELECT ADDDATE(CURRENT_DATE(), number + 1) AS date FROM numbers;


Como se dijo (o al menos se aludió a) en muchas de las maravillosas respuestas ya dadas, este problema se resuelve fácilmente una vez que tiene un conjunto de números para trabajar.

Nota: Lo siguiente es T-SQL, pero es simplemente mi implementación particular de conceptos generales ya mencionados aquí y en Internet en general. Debería ser relativamente simple convertir el código a su dialecto de elección.

¿Cómo? Considera esta consulta:

SELECT DATEADD(d, N, ''0001-01-22'') FROM Numbers -- A table containing the numbers 0 through N WHERE N <= 5;

Lo anterior produce el rango de fechas 1/22/0001 - 1/27/0001 y es extremadamente trivial. Hay 2 piezas clave de información en la consulta anterior: la fecha de inicio de 0001-01-22 y el desplazamiento de 5 . Si combinamos estas dos piezas de información, obviamente tenemos nuestra fecha de finalización. Por lo tanto, dadas dos fechas, la generación de un rango se puede desglosar así:

  • Encuentra la diferencia entre dos fechas dadas (el desplazamiento), fácil:

    -- Returns 125 SELECT ABS(DATEDIFF(d, ''2014-08-22'', ''2014-12-25''))

    El uso de ABS() aquí asegura que el orden de fecha sea irrelevante.

  • Genera un conjunto limitado de números, también es fácil:

    -- Returns the numbers 0-2 SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1 FROM(SELECT ''A'' AS S UNION ALL SELECT ''A'' UNION ALL SELECT ''A'')

    Tenga en cuenta que en realidad no nos importa lo que estamos seleccionando FROM aquí. Solo necesitamos un conjunto con el que trabajar para que podamos contar el número de filas en él. Personalmente utilizo un TVF, algunos usan un CTE, otros usan una tabla de números, entiendes la idea. Abogo por utilizar la solución más eficaz que usted también entienda.

La combinación de estos dos métodos resolverá nuestro problema:

DECLARE @date1 DATE = ''9001-11-21''; DECLARE @date2 DATE = ''9001-11-23''; SELECT D = DATEADD(d, N, @date1) FROM ( SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1 FROM (SELECT ''A'' AS S UNION ALL SELECT ''A'' UNION ALL SELECT ''A'') S ) Numbers WHERE N <= ABS(DATEDIFF(d, @date1, @date2));

El ejemplo anterior es código horrible, pero demuestra cómo todo se combina.

Más diversión

Tengo que hacer mucho este tipo de cosas, así que encapsulé la lógica en dos TVF. El primero genera un rango de números y el segundo usa esta funcionalidad para generar un rango de fechas. La matemática es para garantizar que el orden de entrada no importe y porque quería usar el rango completo de números disponibles en GenerateRangeSmallInt .

La siguiente función requiere ~ 16 ms de tiempo de CPU para devolver el rango máximo de 65536 fechas.

CREATE FUNCTION dbo.GenerateRangeDate ( @date1 DATE, @date2 DATE ) RETURNS TABLE WITH SCHEMABINDING AS RETURN ( SELECT D = DATEADD(d, N + 32768, CASE WHEN @date1 <= @date2 THEN @date1 ELSE @date2 END) FROM dbo.GenerateRangeSmallInt(-32768, ABS(DATEDIFF(d, @date1, @date2)) - 32768) ); GO CREATE FUNCTION dbo.GenerateRangeSmallInt ( @num1 SMALLINT = -32768 , @num2 SMALLINT = 32767 ) RETURNS TABLE WITH SCHEMABINDING AS RETURN ( WITH Numbers(N) AS ( SELECT N FROM(VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240 , (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256 ) V (N) ) SELECT TOP(ABS(CAST(@num1 AS INT) - CAST(@num2 AS INT)) + 1) N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN @num1 <= @num2 THEN @num1 ELSE @num2 END - 1 FROM Numbers A , Numbers B );


De acuerdo ... Prueba esto: http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/
http://dev.mysql.com/doc/refman/5.0/en/loop-statement.html
http://www.roseindia.net/sql/mysql-example/mysql-loop.shtml

Úselo para, digamos, generar una tabla temporal, y luego seleccione * en la tabla temporal. O envíe los resultados uno a la vez.
Lo que dices que quieres hacer no se puede hacer con una instrucción SELECT , pero podría ser factible con cosas específicas de MySQL.
Por otra parte, tal vez necesita cursores: http://dev.mysql.com/doc/refman/5.0/en/cursors.html


Es una buena idea generar estas fechas sobre la marcha. Sin embargo, no me siento cómodo para hacer esto con un rango bastante grande, así que terminé con la siguiente solución:

  1. Creó una tabla "Números de fechas" que contendrá los números utilizados para el cálculo de fechas:

CREATE TABLE DatesNumbers ( i MEDIUMINT NOT NULL, PRIMARY KEY (i) ) COMMENT=''Used by Dates view'' ;

  1. Rellené la tabla usando las técnicas anteriores con números de -59999 a 40000. Este rango me dará fechas de 59999 días (~ 164 años) a 40000 días (109 años) por delante:

INSERT INTO DatesNumbers SELECT ai + (10 * bi) + (100 * ci) + (1000 * di) + (10000 * ei) - 59999 AS i FROM (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a , (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b , (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c , (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d , (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e ;

  1. Creado una vista "Fechas":

SELECT i , CURRENT_DATE() + INTERVAL i DAY AS Date FROM DatesNumbers

Eso es.

  • (+) Consultas fáciles de leer
  • (+) No sobre la marcha números generaciones
  • (+) Da fechas en el pasado y en el futuro y NO HAY UNIÓN a la vista para esto como en esta publicación .
  • (+) Las fechas "Solo en el pasado" o "solo en el futuro" podrían filtrarse utilizando WHERE i < 0 o WHERE i > 0 (PK)
  • (-) se usa la tabla y vista ''temporal''

Esta solución no utiliza bucles, procedimientos o tablas temporales . La subconsulta genera fechas para los últimos mil días, y podría extenderse para ir tan atrás o adelante como lo desee.

select a.Date from ( select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c ) a where a.Date between ''2010-01-20'' and ''2010-01-24''

Salida:

Date ---------- 2010-01-24 2010-01-23 2010-01-22 2010-01-21 2010-01-20

Notas sobre el rendimiento

Probándolo here , el rendimiento es sorprendentemente bueno: la consulta anterior toma 0.0009 segundos.

Si ampliamos la subconsulta para generar aprox. 100.000 números (y por lo tanto 274 años de fechas), se ejecuta en 0.0458 segundos.

A propósito, esta es una técnica muy portátil que funciona con la mayoría de las bases de datos con ajustes menores.

Ejemplo de SQL Fiddle que devuelve 1,000 días


La respuesta aceptada no funcionó para PostgreSQL (error de sintaxis en o cerca de "a").

La forma de hacerlo en PostgreSQL es mediante el uso de la función generate_series , es decir:

SELECT day::date FROM generate_series(''2010-01-20'', ''2010-01-24'', INTERVAL ''1 day'') day; day ------------ 2010-01-20 2010-01-21 2010-01-22 2010-01-23 2010-01-24 (5 rows)


La solución de la vieja escuela para hacer esto sin un bucle / cursor es crear una tabla NUMBERS , que tiene una sola columna Entero con valores que comienzan en 1.

CREATE TABLE `example`.`numbers` ( `id` int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Debe completar la tabla con suficientes registros para cubrir sus necesidades:

INSERT INTO NUMBERS (id) VALUES (NULL);

Una vez que tenga la tabla NUMBERS , puede usar:

SELECT x.start_date + INTERVAL n.id-1 DAY FROM NUMBERS n JOIN (SELECT STR_TO_DATE(''2010-01-20'', ''%Y-%m-%d'') AS start_date FROM DUAL) x WHERE x.start_date + INTERVAL n.id-1 DAY <= ''2010-01-24''

La solución absoluta de baja tecnología sería:

SELECT STR_TO_DATE(''2010-01-20'', ''%Y-%m-%d'') FROM DUAL UNION ALL SELECT STR_TO_DATE(''2010-01-21'', ''%Y-%m-%d'') FROM DUAL UNION ALL SELECT STR_TO_DATE(''2010-01-22'', ''%Y-%m-%d'') FROM DUAL UNION ALL SELECT STR_TO_DATE(''2010-01-23'', ''%Y-%m-%d'') FROM DUAL UNION ALL SELECT STR_TO_DATE(''2010-01-24'', ''%Y-%m-%d'') FROM DUAL

¿Para qué lo usarías?

Para generar listas de fechas o números para IZQUIERDA UNIR a. Lo harías con el fin de ver dónde hay lagunas en los datos, porque estás AJUSTE IZQUIERDO en una lista de datos secuenciales; los valores nulos lo harán obvio cuando existan lagunas.


Más corto que la respuesta aceptada, la misma idea:

(SELECT TRIM(''2016-01-05'' + INTERVAL a + b DAY) date FROM (SELECT 0 a UNION SELECT 1 a UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) d, (SELECT 0 b UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40) m WHERE ''2016-01-05'' + INTERVAL a + b DAY <= ''2016-01-21'')


MSSQL Query

select datetable.Date from ( select DATEADD(day,-(a.a + (10 * b.a) + (100 * c.a)),getdate()) AS Date from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c ) datetable where datetable.Date between ''2014-01-20'' and ''2014-01-24'' order by datetable.Date DESC

Salida

Date ----- 2014-01-23 12:35:25.250 2014-01-22 12:35:25.250 2014-01-21 12:35:25.250 2014-01-20 12:35:25.250


Para Oracle, mi solución es:

select trunc(sysdate-dayincrement, ''DD'') from dual, (select level as dayincrement from dual connect by level <= 30)

Sysdate se puede cambiar a una fecha específica y se puede cambiar el número de nivel para dar más fechas.


Para cualquiera que quiera esto como una vista guardada (MySQL no admite instrucciones de selección anidadas en vistas):

create view zero_to_nine as select 0 as n union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9; create view date_range as select curdate() - INTERVAL (a.n + (10 * b.n) + (100 * c.n)) DAY as date from zero_to_nine as a cross join zero_to_nine as b cross join zero_to_nine as c;

Entonces puedes hacer

select * from date_range

Llegar

date --- 2017-06-06 2017-06-05 2017-06-04 2017-06-03 2017-06-02 ...


Procedimiento + tabla temporal:

DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `days`(IN dateStart DATE, IN dateEnd DATE) BEGIN CREATE TEMPORARY TABLE IF NOT EXISTS date_range (day DATE); WHILE dateStart <= dateEnd DO INSERT INTO date_range VALUES (dateStart); SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY); END WHILE; SELECT * FROM date_range; DROP TEMPORARY TABLE IF EXISTS date_range; END


Usando una expresión de tabla común recursiva (CTE), puede generar una lista de fechas, luego seleccionar de ella. Obviamente, normalmente no querrás crear tres millones de fechas, así que esto solo ilustra las posibilidades. Simplemente podría limitar el rango de fechas dentro del CTE y omitir la cláusula where de la instrucción select utilizando el CTE.

with [dates] as ( select convert(datetime, ''1753-01-01'') as [date] --start union all select dateadd(day, 1, [date]) from [dates] where [date] < ''9999-12-31'' --end ) select [date] from [dates] where [date] between ''2013-01-01'' and ''2013-12-31'' option (maxrecursion 0)

En Microsoft SQL Server 2005, generar la lista CTE de todas las fechas posibles tomó 1:08. Generar cien años tomó menos de un segundo.


Versión SQLite de la solución superior de RedFilters

select d.Date from ( select date(julianday(''2010-01-20'') + (a.a + (10 * b.a) + (100 * c.a))) as Date from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c ) d where d.Date between ''2010-01-20'' and ''2010-01-24'' order by d.Date


mejorado con los días laborables y uniéndose a una tabla de vacaciones personalizada Microsoft MSSQL 2012 para la tabla de fechas de powerpivot https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23b6e90e

with [dates] as ( select convert(datetime, ''2016-01-01'') as [date] --start union all select dateadd(day, 1, [date]) from [dates] where [date] < ''2018-01-01'' --end ) select [date] , DATEPART (dw,[date]) as Wochentag , (select holidayname from holidaytable where holidaytable.hdate = [date]) as Feiertag from [dates] where [date] between ''2016-01-01'' and ''2016-31-12'' option (maxrecursion 0)


prueba esto.

SELECT TO_DATE(''20160210'',''yyyymmdd'') - 1 + LEVEL AS start_day from DUAL connect by level <= (TO_DATE(''20160228'',''yyyymmdd'') + 1) - TO_DATE(''20160210'',''yyyymmdd'') ;


si alguna vez necesitas más de un par de días, necesitas una mesa.

Crea un rango de fechas en mysql

entonces,

select from days.day, count(mytable.field) as fields from days left join mytable on day=date where date between x and y;


si quieres la lista de fechas entre dos fechas:

create table #dates ([date] smalldatetime) while @since < @to begin insert into #dates(dateadd(day,1,@since)) set @since = dateadd(day,1,@since) end select [date] from #dates

* violín aquí: http://sqlfiddle.com/#!6/9eecb/3469


thx Pentium10 - me hiciste unir a :) - esta es mi portación a msaccess - creo que funcionará en cualquier versión:

SELECT date_value FROM (SELECT a.espr1+(10*b.espr1)+(100*c.espr1) AS integer_value, dateadd("d",integer_value,dateserial([start_year], [start_month], [start_day])) as date_value FROM (select * from ( select top 1 "0" as espr1 from MSysObjects union all select top 1 "1" as espr2 from MSysObjects union all select top 1 "2" as espr3 from MSysObjects union all select top 1 "3" as espr4 from MSysObjects union all select top 1 "4" as espr5 from MSysObjects union all select top 1 "5" as espr6 from MSysObjects union all select top 1 "6" as espr7 from MSysObjects union all select top 1 "7" as espr8 from MSysObjects union all select top 1 "8" as espr9 from MSysObjects union all select top 1 "9" as espr9 from MSysObjects ) as a, ( select top 1 "0" as espr1 from MSysObjects union all select top 1 "1" as espr2 from MSysObjects union all select top 1 "2" as espr3 from MSysObjects union all select top 1 "3" as espr4 from MSysObjects union all select top 1 "4" as espr5 from MSysObjects union all select top 1 "5" as espr6 from MSysObjects union all select top 1 "6" as espr7 from MSysObjects union all select top 1 "7" as espr8 from MSysObjects union all select top 1 "8" as espr9 from MSysObjects union all select top 1 "9" as espr9 from MSysObjects ) as b, ( select top 1 "0" as espr1 from MSysObjects union all select top 1 "1" as espr2 from MSysObjects union all select top 1 "2" as espr3 from MSysObjects union all select top 1 "3" as espr4 from MSysObjects union all select top 1 "4" as espr5 from MSysObjects union all select top 1 "5" as espr6 from MSysObjects union all select top 1 "6" as espr7 from MSysObjects union all select top 1 "7" as espr8 from MSysObjects union all select top 1 "8" as espr9 from MSysObjects union all select top 1 "9" as espr9 from MSysObjects ) as c ) as d) WHERE date_value between dateserial([start_year], [start_month], [start_day]) and dateserial([end_year], [end_month], [end_day]);

a los que se hace referencia en MSysObjects simplemente porque el acceso necesita una tabla que contenga al menos 1 registro, en una cláusula from - cualquier tabla con al menos 1 registro sería suficiente.


Para Access 2010 : se requieren múltiples pasos; Seguí el mismo patrón que el publicado anteriormente, pero pensé que podría ayudar a alguien en Access. Funcionó muy bien para mí, no tuve que mantener una tabla de fechas.

Cree una tabla llamada DUAL (similar a cómo funciona la tabla Oracle DUAL)

  • ID (Autonumérico)
  • DummyColumn (Texto)
  • Agregue valores de una fila (1, "DummyRow")

Cree una consulta llamada "ZeroThru9Q"; ingrese manualmente la siguiente sintaxis:

SELECT 0 AS a FROM dual UNION ALL SELECT 1 FROM dual UNION ALL SELECT 2 FROM dual UNION ALL SELECT 3 FROM dual UNION ALL SELECT 4 FROM dual UNION ALL SELECT 5 FROM dual UNION ALL SELECT 6 FROM dual UNION ALL SELECT 7 FROM dual UNION ALL SELECT 8 FROM dual UNION ALL SELECT 9 FROM dual;

Cree una consulta llamada "TodayMinus1KQ" (para las fechas anteriores a hoy); ingrese manualmente la siguiente sintaxis:

SELECT date() - (a.a + (10 * b.a) + (100 * c.a)) AS MyDate FROM (SELECT * FROM ZeroThru9Q) AS a, (SELECT * FROM ZeroThru9Q) AS b, (SELECT * FROM ZeroThru9Q) AS c

Cree una consulta llamada "TodayPlus1KQ" (para las fechas posteriores a hoy); ingrese manualmente la siguiente sintaxis:

SELECT date() + (a.a + (10 * b.a) + (100 * c.a)) AS MyDate FROM (SELECT * FROM ZeroThru9Q) AS a, (SELECT * FROM ZeroThru9Q) AS b, (SELECT * FROM ZeroThru9Q) AS c;

Cree una consulta de unión llamada "TodayPlusMinus1KQ" (para fechas +/- 1000 días):

SELECT MyDate FROM TodayMinus1KQ UNION SELECT MyDate FROM TodayPlus1KQ;

Ahora puedes usar la consulta:

SELECT MyDate FROM TodayPlusMinus1KQ WHERE MyDate BETWEEN #05/01/2014# and #05/30/2014#


DELIMITER $$ CREATE PROCEDURE GenerateRangeDates(IN dateStart DATE, IN dateEnd DATE) BEGIN CREATE TEMPORARY TABLE IF NOT EXISTS dates (day DATE); loopDate: LOOP INSERT INTO dates(day) VALUES (dateStart); SET dateStart = DATE_ADD(dateStart, INTERVAL 1 DAY); IF dateStart <= dateEnd THEN ITERATE loopDate; ELSE LEAVE loopDate; END IF; END LOOP loopDate; SELECT day FROM dates; DROP TEMPORARY TABLE IF EXISTS dates; END $$ -- Call procedure call GenerateRangeDates( now() - INTERVAL 40 DAY, now() );


set language ''SPANISH'' DECLARE @table table(fechaDesde datetime , fechaHasta datetime ) INSERT @table VALUES(''20151231'' , ''20161231''); WITH x AS ( SELECT DATEADD( m , 1 ,fechaDesde ) as fecha FROM @table UNION ALL SELECT DATEADD( m , 1 ,fecha ) FROM @table t INNER JOIN x ON DATEADD( m , 1 ,x.fecha ) <= t.fechaHasta ) SELECT LEFT( CONVERT( VARCHAR, fecha , 112 ) , 6 ) as Periodo_Id ,DATEPART ( dd, DATEADD(dd,-(DAY(fecha)-1),fecha)) Num_Dia_Inicio ,DATEADD(dd,-(DAY(fecha)-1),fecha) Fecha_Inicio ,DATEPART ( mm , fecha ) Mes_Id ,DATEPART ( yy , fecha ) Anio ,DATEPART ( dd, DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha))) Num_Dia_Fin ,DATEADD(dd,-(DAY(DATEADD(mm,1,fecha))),DATEADD(mm,1,fecha)) ultimoDia ,datename(MONTH, fecha) mes ,''Q'' + convert(varchar(10), DATEPART(QUARTER, fecha)) Trimestre_Name FROM x OPTION(MAXRECURSION 0)