2013-07-16 16 views
10

什麼是快速/可讀的方式從包含數字列表的「nothing」中選擇一個關係。我想通過設置開始和結束值來定義哪些數字。我正在使用Postgres SQL和SQLite,並且對通用解決方案感興趣,這些解決方案可以在兩個/多個平臺上工作。SQL:從「nothing」中選擇一個數字列表

所需的輸出關係:

# x 
    0 
    1 
    2 
    3 
    4 

我知道,我可以從「無」中選擇一個行:SELECT 0,1,2,3,4但這個選擇值列而不是行,需要在查詢中指定的所有值,而不是隻使用我的開始和結束值:04

在Postgres裏,你有一個特殊generate_series功能這種情況:

SELECT * FROM generate_series(0,4) x; 

這工作得很好,但就是不規範。我還可以使用臨時表想象一些複雜的解決方案,但我想有一些通用的,簡單的,如:

SELECT * FROM [0..4] 

也許使用SEQUENCE陳述或SELECT 0SELECT 4一些神奇的組合?

+1

你可能會使用高達1000的數字我會說 - 也許在表格上放一個索引。否則,請創建諸如numbers_to_1000,numbers_to_1000000之類的視圖來封裝這些crossjoins。 –

+0

@Juve,你可以接受一些答案或發佈你的答案並接受它嗎? –

+0

當我開始尋找時,我很驚訝於這個簡單外觀的任務要實現的多麼尷尬。這裏有一些文章提供了更多的可能性(但是它表明沒有什麼能夠從PostgreSQL上傳GENERATE_SERIES()):https://blog.jooq.org/2013/11/19/how-to-create-a-range-from-1 -to-10-in-sql/ – Dodecaphone

回答

2

感謝您的所有答案! 接着我意識到,使用numbers table是不是太複雜,運作良好,並快速在兩個/多平臺的討論:

CREATE TABLE integers (i integer); 
INSERT INTO integers (i) VALUES (0); 
INSERT INTO integers (i) VALUES (1); 
... 
INSERT INTO integers (i) VALUES (9); 
SELECT (hundreds.i * 100) + (tens.i * 10) + units.i AS x 
FROM integers AS units 
    CROSS JOIN integers AS tens 
    CROSS JOIN integers AS hundreds 

你剛纔創建這個表一次,每當你需要一個數字範圍可以使用它。

4

那麼在SQL服務器(和PostgreSQL)我會使用遞歸公用表表達式:SQL ServerPostgreSQL

with recursive Numbers as (
    select 0 as Number 
    union all 
    select Number + 1 
    from Numbers 
    where Number < 4 
) 
select Number 
from Numbers 

SQL FIDDLE EXAMPLE

但是,據我所知,有SQLite中沒有WITH。

因此,可能的解決方案可能是

  • 創建一個用戶自定義函數(this可能是有益的)
  • 從0創建數字的表,你永遠需要最大數量,然後剛剛從像這樣選擇:

    select Number from Numbers where Number >= 0 and Number <= 4 
    
+0

遞歸CTE也可以在Postgres中工作(實際上它是唯一的「標準」方式) - –

+0

真的,我剛剛試圖幫助SQLite,因爲他知道如何在PostgreSQL中做到這一點,但是謝謝,我將編輯答案 –

+1

雖然遞歸CTE可以在大多數現代DBMS中工作,但它已被證明是[生成序列的非常低效的方式](http:// www .sqlperformance.com/2013/01/T-SQL查詢/生成-A-設置-2)。我認爲數字表是迄今爲止最好的方法。 – GarethD

4

一個簡單的方法在PostgreSQL中做到這一點,SQLite是如下:

sqlite> select 1 union select 2 union select 3; 
1 
2 
3 

應該在大多數RDBMS系統工作,但IIRC在Oracle中,你將不得不使用:

select 1 from dual union select 2 from dual union select 3 from dual; 

但我沒有一個Oracle數據庫來測試它。

0

一些其他替代(在Postgres的嘗試,但應該與他人合作)

select (0) as count union values (1),(2),(3),(4),(5)

擴展這個SQL的代碼將是直線前進。