Mat*_*s F 3 sql-server sql-server-2008
我的客户有销售区域,每个销售区域都包含一个邮政编码列表.这些地区相当大,可以更容易地存储,如:
区域包括邮政编码范围从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')
Run Code Online (Sandbox Code Playgroud)
将导致SearchableZip表中的这个条目
AreaCode StartZip EndZip
-------------------- -------------------- -------------------------
Area1 00544 00602
Area2 00604 00604
Area2 00606 00606
Area3 00501 00604
Area3 00610 00612
Run Code Online (Sandbox Code Playgroud)
是否可以使用sql脚本创建SearchableZip?
编辑
我修复了表声明和输出数据
是的,可以通过单个查询从列表中获取范围.为此你将使用CTE,排名和一些灰质:
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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
此输出与您的输出不匹配,但它与源数据匹配.
UPDATE
如果Zip表是用于确定邮政编码列表的连续性的参考表,那么上述解决方案应该像这样修改:
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
Run Code Online (Sandbox Code Playgroud)