2011-07-22 28 views
3

我的客戶有銷售地區,其中每個銷售地區由郵政編碼列表組成。 區域是相當大的,並且可以更容易存儲格式,如:確定是否有幾個郵政編碼是連續的

地區包括郵政編碼範圍爲00602至10012和20020至30020.

我怎樣才能從郵政編碼到列表中得到這種郵政編碼範圍的列表?

考慮以下數據

--This would be my list of all available zip codes in us: 

CREATE TABLE [Zip](
    [Zip] [nvarchar](20) , 
    [State] [nvarchar](50) , 
) 

--This would be the Sales Region List 

CREATE TABLE [dbo].[SalesRegion](
    [AreaCode] [nvarchar](50) 
) 

--This would be the original large list Zip Codes for the SalesRegions 

CREATE TABLE [dbo].[EnteredZip](
    [Zip] [nvarchar](20) , 
    [AreaCode] [nvarchar](50) 
) 

--This is where I would like to store the Zip Code Ranges 

CREATE TABLE [dbo].[SearchableZip](
    [StartZip] [nvarchar](20) , 
    [EndZip] [nvarchar](20) , 
    [AreaCode] [nvarchar](50) 
) 

--Here is my sample Data: 

--Some Zip Codes in US 
insert into dbo.Zip (Zip,[State]) values ('00501' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00544' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00601' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00602' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00603' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00604' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00605' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00606' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00610' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00611' ,'PR') 
insert into dbo.Zip (Zip,[State]) values ('00612' ,'PR') 


--Some Sales Regions 

Insert Into dbo.SalesRegion (AreaCode) values('Area1') 
Insert Into dbo.SalesRegion (AreaCode) values('Area2') 
Insert Into dbo.SalesRegion (AreaCode) values('Area3') 


--The zip codes of the Sales Regions 
insert Into EnteredZip (Zip,AreaCode) values ('00544' , 'Area1') 
insert Into EnteredZip (Zip,AreaCode) values ('00601' , 'Area1') 
insert Into EnteredZip (Zip,AreaCode) values ('00602' , 'Area1') 

insert Into EnteredZip (Zip,AreaCode) values ('00604' , 'Area2') 
insert Into EnteredZip (Zip,AreaCode) values ('00606' , 'Area2') 

insert Into EnteredZip (Zip,AreaCode) values ('00501' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00544' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00601' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00602' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00603' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00604' , 'Area3') 

insert Into EnteredZip (Zip,AreaCode) values ('00610' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00611' , 'Area3') 
insert Into EnteredZip (Zip,AreaCode) values ('00612' , 'Area3') 

將導致表本項SearchableZip

AreaCode    StartZip    EndZip 
-------------------- -------------------- ------------------------- 
Area1    00544    00602 
Area2    00604    00604 
Area2    00606    00606 
Area3    00501    00604 
Area3    00610    00612 

是否有可能與SQL腳本創建SearchableZip?

編輯

我固定的表聲明和輸出數據

+1

的'插入EnteredZip ...'語句不一致。它們不匹配表格的聲明,並且列值的順序錯誤。 –

+0

如果您遇到性能問題,這不是解決問題的方法。編輯您的問題,並粘貼查詢執行計劃,以查找效果不佳的查詢。就目前而言,它看起來像是在猜測解決方案。猜測不好。 –

+0

你是對的,但我必須嘗試一下。即使它是一種糟糕的方式(它真的可能是) –

回答

7

是的,可以通過單個查詢從列表中獲取範圍。對於您將使用CTEranking,還有一點點grey matter

WITH ranked AS (
    SELECT 
    Zip, 
    AreaCode, 
    ZipGroup = CAST(Zip AS int) 
      - ROW_NUMBER() OVER (PARTITION BY AreaCode ORDER BY Zip) 
    FROM EnteredZip 
) 
SELECT 
    StartZip = MIN(Zip), 
    EndZip = MAX(Zip), 
    AreaCode 
FROM ranked 
GROUP BY AreaCode, ZipGroup 

輸出:

StartZip    EndZip    AreaCode 
-------------------- -------------------- ------------------------- 
00544    00544    Area1 
00601    00602    Area1 
00604    00604    Area2 
00606    00606    Area2 
00501    00501    Area3 
00544    00544    Area3 
00601    00604    Area3 
00610    00612    Area3 

此輸出不匹配你的,但它確實匹配的源數據。


UPDATE

如果郵編表是用於確定的郵政編碼的列表的鄰接的參考表,然後將上述溶液應修改這樣的:

WITH ZipRanked AS (
    SELECT 
    Zip, 
    State, 
    ZipRank = ROW_NUMBER() OVER (PARTITION BY State ORDER BY Zip) 
    FROM Zip 
), 
EnteredZipRanked AS (
    SELECT 
    e.Zip, 
    e.AreaCode, 
    ZipGroup = z.ZipRank 
      - ROW_NUMBER() OVER (PARTITION BY e.AreaCode ORDER BY e.Zip) 
    FROM EnteredZip e 
    INNER JOIN ZipRanked z ON e.Zip = z.Zip 
) 
SELECT 
    StartZip = MIN(Zip), 
    EndZip = MAX(Zip), 
    AreaCode 
FROM EnteredZipRanked 
GROUP BY AreaCode, ZipGroup 
+0

現在樣本數據中的輸出是正確的。您提供的查詢無法工作,因爲表Zip是必需的。例如Area1有StartZip 00544和Endzip 00602,因爲在這兩個代碼之間不存在其他郵編,那麼00601.Sry通過給出錯誤的輸入數據使得這更難。 –

+1

我明白這一點,儘管樣本中的Zip表不包含輸入郵政編碼列表中的「00601」郵政編碼。這可能是在真實的情況下,還是你錯誤地忽略了代碼? –

+0

好點:我糾正了輸入數據。 –

0

首先,我要告訴你的是什麼,我想打算做給我的印象是一個壞主意。 EnteredZip表格適用於存儲郵政編碼所屬的區域。 (只要你把PRIMARY KEY約束上ZIP)

它看起來這是大致相當於你的目標,

select areacode, min(zip), max(zip) 
from enteredzip 
group by areacode 
order by areacode 

,但它不能在你的輸出相匹配。坦率地說,你的示例輸出對我來說沒有意義。

Area1只有一行,但郵政編碼不是連續的。 Area2有兩行,但每個都有一個郵政編碼。 Area3有兩行,但ZIP不是連續的。

等等。 。 。

是否連續是否意味着您在示例數據中的INSERT語句之間插入了空行?

如果是這樣的話,那麼你需要存儲更多的數據。您必須確定應將哪些郵政編碼視爲連續的,並將這些資料存儲在表格中。 (另外,您在區域2中留出了空行。)

+0

我編輯了示例輸出,以便更容易閱讀。我看到您提出的關於不是一個好主意的觀點。如果它解決了我的性能問題,我只想嘗試。如果區域真的很大,我可能有機會。索引已經到位,但這還不夠。 –

相關問題