2010-02-19 10 views
5

¿Se puede hacer cualquiera de estas consultas en SQL?SELECCIONAR cualquier sistema FROM

SELECT dates FROM system 
WHERE dates > 'January 5, 2010' AND dates < 'January 30, 2010' 

SELECT number FROM system 
WHERE number > 10 AND number < 20 

Me gustaría crear un generate_series, y es por eso que estoy pidiendo.

+4

No está claro lo que está preguntando. ¿Cuál es el problema que estás teniendo? ¿Está preguntando si puede consultar todas las tablas en todas las bases de datos o pregunta si puede consultar una tabla llamada "sistema"? El segundo ejemplo debería funcionar bien. El primer ejemplo no funcionará como crees, son dos piezas de texto, no fechas. Deberá guardar las fechas en un formato adecuado. – Tom

+1

Creo que se refieren a consultas simples para obtener listas de fechas o números entre rangos determinados, sobre la marcha. – MartW

+2

@Tom: supongo que está pidiendo 'generate_series'. – Quassnoi

Respuesta

12

Supongo que desea generar un conjunto de registros de número arbitrario de valores, en función del primer y último valor de la serie.

En PostgreSQL:

SELECT num 
FROM generate_series (11, 19) num 

En SQL Server:

WITH q (num) AS 
     (
     SELECT 11 
     UNION ALL 
     SELECT num + 1 
     FROM q 
     WHERE num < 19 
     ) 
SELECT num 
FROM q 
OPTION (MAXRECURSION 0) 

En Oracle:

SELECT level + 10 AS num 
FROM dual 
CONNECT BY 
     level < 10 

En MySQL:

Lo siento.

+0

ah. me la ganaste ... muy buena respuesta +1 – EvilTeach

+0

MYSQL: 'SELECT num from (selecciona @num: = @ num + 1 como num de big_table, (selecciona @num: = 10) num) como q WHERE num <= 19' (http://stackoverflow.com/a/6871220/2115135) –

+0

@JakubKania: primero debe tener 'big_table'. – Quassnoi

0

No estoy seguro si esto es lo que pregunta, pero si quieres seleccionar algo que no está en una tabla, puedes usar 'DUAL'

select 1, 2, 3 from dual; 

devolverá una fila con 3 columnas, contiene esos tres dígitos.

Seleccionar desde dual es útil para ejecutar funciones. Una función se puede ejecutar con la entrada manual en lugar de seleccionar algo más en ella. Por ejemplo:

select some_func('First Parameter', 'Second parameter') from dual; 

devolverá los resultados de some_func.

0

En SQL Server puede usar la palabra clave BETWEEN.

Enlace: http://msdn.microsoft.com/nl-be/library/ms187922(en-us).aspx

+0

¿Se puede usar esto de otra manera que en una cláusula where? O bien, ¿se puede usar una cláusula where aparte de seleccionar de una tabla? –

+0

Solo hay que recordar que BETWEEN incluye los límites mientras que el ejemplo del OP los excluye. – DyingCactus

0

puede seleccionar un rango utilizando WHERE y AND WHERE. No puedo hablar de rendimiento, pero es posible.

+0

Puedes. Pero AFAIK, 'WHERE' debe usarse cuando se selecciona desde una tabla o vista. La pregunta parece estar preguntando cómo generar fechas o números, es decir, NO desde una tabla o vista que ya está poblada. –

+0

¿Qué es 'AND WHERE'? –

1

En Oracle

WITH 
START_DATE AS 
(
    SELECT TO_CHAR(TO_DATE('JANUARY 5 2010','MONTH DD YYYY'),'J') 
    JULIAN FROM DUAL 
), 
END_DATE AS 
(
    SELECT TO_CHAR(TO_DATE('JANUARY 30 2010','MONTH DD YYYY'),'J') 
    JULIAN FROM DUAL 
), 
DAYS AS 
(
    SELECT END_DATE.JULIAN - START_DATE.JULIAN DIFF 
    FROM START_DATE, END_DATE 
) 
SELECT TO_CHAR(TO_DATE(N + START_DATE.JULIAN, 'J'), 'MONTH DD YYYY') 
     DESIRED_DATES 
FROM 
START_DATE, 
(
    SELECT LEVEL N 
    FROM DUAL, DAYS 
    CONNECT BY LEVEL < DAYS.DIFF 
) 
1

Si desea obtener la lista de días, con un SQL como

seleccione ...como los días en que se encuentra entre date '2010-01-20' y '2010-01-24'

y devolver los datos como:

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

Esta solución utiliza ningún bucle, 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 de

prueba a cabo here, el rendimiento es sorprendentemente bueno: la consulta anterior toma 0,0009 seg.

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

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

+0

Preferiría usar FUNCIÓN DE FECHA de MVJ es mucho más flexible y el rendimiento es fantástico. http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519 – JonH

+0

Eso no está disponible en MySQL ni en Postgresql y SQLite – Pentium10

0

La solución más simple a este problema es una tabla Tally o Numbers. Esa es una tabla que simplemente almacena una secuencia de números enteros y/o fechas

Create Table dbo.Tally ( 
         NumericValue int not null Primary Key Clustered 
         , DateValue datetime NOT NULL 
         , Constraint UK_Tally_DateValue Unique (DateValue) 
         ) 
GO 

;With TallyItems 
As (
    Select 0 As Num 
    Union All 
    Select ROW_NUMBER() OVER (Order By C1.object_id) As Num 
    From sys.columns as c1 
     cross join sys.columns as c2 
    ) 
Insert dbo.Tally(NumericValue, DateValue) 
Select Num, DateAdd(d, Num, '19000101') 
From TallyItems 
Where Num

Una vez que haya esa mesa poblada, que no será necesario tocarlo a no ser que desee para expandirla. Combiné las fechas y los números en una sola tabla, pero si necesitabas más números que fechas, podrías dividirlos en dos tablas. Además, llené arbitrariamente la tabla con 100K filas, pero obviamente podría agregar más. Todos los días entre 1900-01-01 y 9999-12-31 toman alrededor de 434,000 filas. Probablemente no necesitará tantos, pero incluso si lo hizo, el almacenamiento es muy pequeño.

Independientemente, esta es una técnica común para resolver muchos problemas de huecos y secuencias. Por ejemplo, todas sus consultas originales se ejecutaron en menos de una décima de segundo. También puede usar este tipo de tabla para resolver problemas de huecos como:

Select NumericValue 
From dbo.Tally 
    Left Join MyTable 
     On Tally.NumericValue = MyTable.IdentityColumn 
Where Tally.NumericValue Between SomeLowValue And SomeHighValue 
Cuestiones relacionadas