ВЫБЕРИТЕ любого ИЗ системы

Какой-либо из этих запросов может быть сделан в SQL?

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

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

Я хотел бы создать a generate_series, и вот почему я спрашиваю.

5
задан 7 revs, 5 users 45% 12 April 2010 в 16:04
поделиться

8 ответов

Я предполагаю, что вы хотите сгенерировать набор записей с произвольным количеством значений, основанный на первом и последнем значении в серии.

В PostgreSQL:

SELECT  num
FROM    generate_series (11, 19) num

В 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)

В Oracle:

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

В MySQL:

Извините.

12
ответ дан 18 December 2019 в 11:55
поделиться

Типа дат ... Майкл Валентайн Джонс из команды SQL имеет УДИВИТЕЛЬНУЮ функцию даты

Проверьте это здесь:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519

1
ответ дан 18 December 2019 в 11:55
поделиться

В SQL Server вы можете использовать ключевое слово BETWEEN.

Ссылка: http://msdn.microsoft.com/nl-be/library/ms187922(en-us).aspx

0
ответ дан 18 December 2019 в 11:55
поделиться

Не уверен, что это именно то, что вы спрашиваете, но если вы хотите выбрать что-то не из таблицы, вы можете использовать 'DUAL'

select 1, 2, 3 from dual;

вернет строку с 3 столбцами, содержащую эти три цифры.

Выбор из двойного полезно для выполнения функций. Функцию можно запускать с ручным вводом вместо того, чтобы выбирать в ней что-то еще. Например:

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

вернет результаты some_func.

0
ответ дан 18 December 2019 в 11:55
поделиться

Вы можете выбрать диапазон, используя ГДЕ и И ГДЕ . Я не могу говорить о производительности, но это возможно.

0
ответ дан 18 December 2019 в 11:55
поделиться

В 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
ответ дан 18 December 2019 в 11:55
поделиться

Если вы хотите получить список дней, используйте SQL типа

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

И верните данные типа:

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

Это решение не использует циклы, процедуры или временные таблицы. Подзапрос генерирует даты за последнюю тысячу дней, и может быть расширен для возврата назад или вперед по вашему желанию.

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' 

Вывод:

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

Замечания по производительности

Протестировав его здесь, можно сказать, что производительность удивительно хорошая: вышеприведенный запрос занимает 0,0009 сек.

Если мы расширим подзапрос для генерации примерно 100 000 чисел (и, соответственно, дат за 274 года), он выполняется за 0,0458 сек.

Кстати, это очень портативная техника, которая работает с большинством баз данных с небольшими корректировками.

1
ответ дан 18 December 2019 в 11:55
поделиться

Простейшим решением этой проблемы является таблица Tally или Numbers. Это таблица, которая просто хранит последовательность целых чисел и/или дат

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 

Как только вы заполните эту таблицу, вам никогда не придется к ней прикасаться, если только вы не захотите ее расширить. Я объединил даты и числа в одну таблицу, но если вам нужно больше чисел, чем дат, то вы можете разбить ее на две таблицы. Кроме того, я произвольно заполнил таблицу 100K строк, но вы можете добавить больше. Каждый день с 1900-01-01 по 9999-12-31 занимает около 434K строк. Вероятно, вам не понадобится столько, но даже если и понадобится, хранилище будет крошечным.

Независимо от этого, это обычная техника для решения многих проблем с пробелами и последовательностями. Например, все ваши исходные запросы выполнялись менее чем за десятые доли секунды. Вы также можете использовать такую таблицу для решения проблем с пробелами, например:

Select NumericValue
From dbo.Tally
    Left Join MyTable
        On Tally.NumericValue = MyTable.IdentityColumn
Where Tally.NumericValue Between SomeLowValue And SomeHighValue
0
ответ дан 18 December 2019 в 11:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: