2016-12-09 100 views
1

我有一個表格,每個州有兩個郵政編碼之間有幾行排隊範圍。我希望能夠採取這兩個範圍,並顯示在他們各自的行上的兩個範圍之間的每個值。 EX下面。Dispaying兩個範圍之間的所有數據點

Zip Start Zip End  State 
00501  06390  NY 
10001  10314  NY 
10451  11003  NY 

我希望數據顯示爲

00501 NY 
00502 NY 
00503 NY 
00504 NY 

任何幫助將不勝感激。

DROP TABLE IF EXISTS yourTable; 
CREATE TABLE yourTable as 
Select '00501' as zipstart,'06390' as zipend,'NY' as state union 
select'10001','10314','NY'union 
select'10451','11003','NY' 

Distributed by (ZipStart,ZipEnd,State); 

WITH cte AS (
    SELECT * 
    FROM 
     (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n) 
) 

, cteTally AS (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as Num 
    FROM 
     cte c1 
     CROSS JOIN cte c2 
     CROSS JOIN cte c3 
     CROSS JOIN cte c4 
     CROSS JOIN cte c5 
) 

SELECT 
    SUBSTRING(ZipStart || CAST(tt.Num AS VARCHAR(100)),1,5) ZipSTart 
    ,t.zipend,t.State 
FROM 
    yourTable t 
    INNER JOIN cteTally tt 
    ON tt.Num <= CAST(t.ZipEnd AS INT) 
    AND tt.Num >= CAST(t.ZipStart AS INT) 
+0

你有什麼已經嘗試過,什麼問題(S)你的經驗嗎? – 3N1GM4

+0

最初這是在使用硬編碼值和臨時表的SQL服務器中完成的。我們現在在PGAdmin中,應用程序不能再處理大量的值。 我希望能夠在子查詢中使用這個更大的報告。謝謝 – Garrett

+2

好吧...這是使用SQL Server還是PostgresSql?選一個。 – SqlZim

回答

1

這是一個在PostgreSQL和其他幾個平臺上工作的Sql server版本。最多可處理100,000個數字以擴展簡單地在cteTally定義中添加更多交叉連接。

IF OBJECT_ID('tempdb..#yourTable') IS NOT NULL 
    BEGIN 
     DROP TABLE #yourTable 
    END 

CREATE TABLE #yourTable (ZipStart VARCHAR(5), ZipEnd VARCHAR(5), State CHAR(2)); 
INSERT INTO #yourTable VALUES 
('00501','06390','NY') 
,('10001','10314','NY') 
,('10451','11003','NY'); 

WITH cte AS (
    SELECT * 
    FROM 
     (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n) 
) 

, cteTally AS (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY (SELECT 1)) as Num 
    FROM 
     cte c1 --10 
     CROSS JOIN cte c2 --100 
     CROSS JOIN cte c3 --1,000 
     CROSS JOIN cte c4 --10,000 
     CROSS JOIN cte c5 --100,000 
) 

SELECT 
    RIGHT('00000' || CAST(tt.Num AS VARCHAR(100)),5) as GeneratedZip 
    ,t.ZipStart 
    ,t.ZipEnd 
    ,t.State 
FROM 
    #yourTable t 
    INNER JOIN cteTally tt 
    ON tt.Num <= CAST(t.ZipEnd AS INT) 
    AND tt.Num >= CAST(t.ZipStart AS INT) 

和PostgreSQL的具體和平臺支持generate_series退房Dudu's answer

+1

代替沒問題。我們都有資格偶爾參加「Magoo先生時刻」我的妻子保留我的名單 –

+0

您好Matt,感謝您的幫助。只是爲了澄清我需要Postgres版本。不過,我必須擁有較舊版本的PGAdmin,因爲我必須進行一些修改才能使其正常運行。我的報告運行,但只顯示最初的3個臨時表值幾千次。 – Garrett

+0

@Matt道歉我不熟悉如何在評論中發佈代碼。我已經將最初的問題用新代碼修改爲底部。 – Garrett

0

這是Sql Server的。我會把它留在這裏,只是因爲我花時間寫了它。

這是非常簡單的數字表。

rextester:http://rextester.com/MEFE32862

號碼錶,從@AaronBertrand's article on generating a set被盜。

begin; 
create table dbo.zip_ranges (id int ,StateName varchar(32) ,[State] char(2) ,Zip_Start int ,Zip_End int) 
    insert into dbo.zip_ranges (id, StateName, [State], Zip_Start, Zip_End) values 
    (1 ,'New York (Fishers Is)' ,'NY' ,501 ,6390) ,(2 ,'New York' ,'NY' ,10001 ,10314),(3 ,'New York' ,'NY' ,10001 ,10314) ,(4 ,'Ohio' ,'OH' ,43001 ,45999) 
    create unique clustered index n on dbo.zip_ranges(Id) 
end; 
/* 100,000 number table - stolen from @AaronBertrand https://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1 */ 
begin; 
    select top (100000) n = convert(int, row_number() over (order by s1.[object_id])) 
    into dbo.numbers 
    from sys.all_objects as s1 
     cross join sys.all_objects as s2 
    option (maxdop 1); 
    create unique clustered index n on dbo.numbers(n) 
end; 

select 
     --Zip=n.n 
     --Zip=left('00000',5-len(n.n))+convert(varchar(5),n.n) 
     Zip=right('00000'+convert(varchar(5),n.n),5) /* grabbed this conversion from @Matt instead of my clunky one */ 
     , z.[State] 

from dbo.zip_ranges z 
    inner join dbo.numbers n on n >= z.zip_start and n <= z.zip_end 
    where z.[State]='NY' 
    order by n 
+1

@a_horse_with_no_name這個問題最初是爲sql-server標記的。 – SqlZim

3

PostgreSQL的

select to_char(zip,'FM00000') as zip 
     ,state 

from t,generate_series("Zip Start"::int,"Zip End"::int) gs(zip) 
; 
+0

+1我特別同意PostgreSQL(以及支持的平臺)generate_series對於這種情況是一種更簡單的方法,並且如果需要實際生成一個演播提示表。 – Matt

+0

@Garrett - 一種接受答案的提示(通過標記** V **標記留下) –

相關問題