2010-02-19 78 views
5

這些查詢可以在SQL中完成嗎?選擇任何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 

我想創建一個generate_series,這就是爲什麼我問。

+4

目前尚不清楚您要問什麼。你有什麼問題?你問你是否可以查詢所有數據庫中的所有表,或者你問是否可以查詢名爲「system」的表?第二個例子應該可以正常工作。第一個例子不會像你想象的那樣工作,那是兩段文本,而不是日期。您需要以適當的格式存儲日期。 – Tom 2010-02-19 17:29:28

+1

我認爲他們的意思是簡單的查詢,以獲取給定範圍之間的日期或數字列表。 – MartW 2010-02-19 17:31:17

+2

@Tom:我假設他要求'generate_series'。 – Quassnoi 2010-02-19 17:31:34

回答

12

我假設你想根據系列中的第一個和最後一個值生成任意數量值的記錄集。

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

對不起。

+0

啊。你擊敗了我...非常好的答案+1 – EvilTeach 2010-02-19 18:13:07

+0

MYSQL:'SELECT num from(select @num:= @ num + 1 as num from big_table,(select @num:= 10)num)as WHERE num <= 19'(http://stackoverflow.com/a/6871220/2115135) – 2013-03-04 23:00:50

+0

@JakubKania:你首先需要'big_table'。 – Quassnoi 2013-03-05 09:16:20

0

不知道這是否就是你'如果你想從桌上選擇一些東西,你可以使用'DUAL'

select 1, 2, 3 from dual; 

將返回一行3列,包含這三位數字。

從dual中選擇對於運行函數很有用。可以使用手動輸入運行功能,而不是選擇其他功能。例如:

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

將返回some_func的結果。

0

您可以通過使用WHEREAND WHERE選擇範圍。我不能對演出說話,但可能。

+0

你可以。但是AFAIK,從表格或視圖中選擇時必須使用'WHERE'。這個問題似乎在問如何生成日期或數字,即不是從已經填充的表或視圖中生成日期或數字。 – 2010-02-19 17:44:42

+0

什麼是'和哪裏'? – 2010-02-19 18:10:31

1

在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

如果你想獲得天的列表中,用SQL像

選擇...如天凡date是「2010-01-20」和「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 

注意事項性能

測試出來here,表現出奇的好:上面的查詢需要0.0009秒。

如果我們擴展子查詢來生成約。 100,000個數字(因此約274年的日期),它運行在0.0458秒。順便說一下,這是一種非常便攜的技術,可以在大多數數據庫中進行微小的調整。

+0

我寧願使用MVJ的日期功能,它更加靈活,性能非常好。 http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519 – JonH 2010-02-19 20:05:53

+0

那是不是可以在MySQL也不在PostgreSQL和SQLite – Pentium10 2010-02-19 20:10:12

0

這個問題的最簡單的解決方案是一個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