从100,101,102等行创建范围(100-106、107、111-119)

问题描述 投票:1回答:3

我有一张桌子,上面满是美国的所有邮政编码。您可能知道邮政编码不一定是一个接一个,所以对于密歇根州,我有这些邮政编码(只是一个示例):

48001,48002,48003,48004,48005,48006,48007,48009,48012,48014,48015,48017

我需要做的是最后一行,例如:

48001-48007,48009,48012,48014-48015,48017

[您会看到我正在将按顺序排列的邮政编码合并到起始-结束范围内,并且如果邮政编码不是按顺序排列的,那么它本身就是单独的。

我将仅使用邮政编码的子集,而不是整个美国。因此,假设我有一个包含要使用的邮政编码的临时表,则可以根据需要填充该临时表。现在,此临时表只有一个邮政编码字段,但是可以定义它,但是需要定义。

我可以使用临时表,游标或其他任何东西,它将在存储过程中完成。如果您想知道为什么,我们有销售代表,每个代表都有特定的邮政编码,我们需要打印出某些代表。当客户服务部门接到客户的电话时,他们可以快速查看打印的图纸并扫描以查看负责该邮编的销售代表。

所以打印的纸看起来像:

Jim Smith...........48001-48007,48009,48012,48014-48015,48017
Heather Jones...59014, 59017, 59018-59022  (completely fake numbers, just as an example)

我意识到纸张已经过时了,我们可以使用网站或任何其他方法来完成此操作,但是出于任何原因,都必须打印纸张,因此我尝试尽可能地压缩邮政编码以便打印。

sql sql-server-2014
3个回答
1
投票

您可以尝试以下方法。

create table zipcodes(zcode int);

insert into zipcodes
 select *
   from (values(48001),(48002),(48003),(48004),(48005),(48006),(48007),(48009),(48012),(48014),(48015),(48017))t(x);


select case when count(*) >1 then 
             concat(min(zcode),'-',max(zcode)) 
            else concat(max(zcode),'')
        end as concat_zcodes
from (
        select zcode
               ,ROW_NUMBER() over(order by zcode asc)  as rnk
               ,zcode - ROW_NUMBER() over(order by zcode asc) as grp
          from zipcodes
     )x
group by x.grp

0
投票

如果您有一列包含州和邮政编码的列,那么这是一个空白问题。对于各个范围:

select state,
       (case when min(zip_code) = max(zip_code)
             then min(zip_code)
             else concat(min(zip_code), '-', max(zip_code)
        end) as zips
from (select t.*,
             convert(int, zip_code) - row_number() over (partition by state order by zip_code) as grp
      from t
     ) t
group by state, grp;

为获得最终结果,请再次汇总:

select state, string_agg(zip_code, ',') 
from (select state,
             (case when min(zip_code) = max(zip_code)
                   then min(zip_code)
                   else concat(min(zip_code), '-', max(zip_code)
              end) as zips
      from (select t.*,
                   convert(int, zip_code) - row_number() over (partition by state order by zip_code) as grp
            from t
           ) t
      group by state, grp
     ) sg
group by state;

在旧版本中,您需要使用XML hack进行最终聚合。


0
投票

您要将同一位客户的相邻拉链分组在一起。我会使用lag()和累积sum()来定义组,以解决缺口和孤岛问题:

select 
    customer_id,
    case when min(zip) = max(zip) 
        then concat(min(zip), '')
        else concat(min(zip),  '-', max(zip))
    end zip_range
from (
    select 
        customer_id,
        zip,
        sum(case when zip = lag_zip + 1 then 0 else 1 end) 
            over(partition by customer_id order by zip) grp
    from (
        select
            customer_id,
            zip,
            lag(zip) over(partition by customer_id order by zip) lag_zip
        from mytable t
    ) t
) t
group by customer_id, grp
© www.soinside.com 2019 - 2024. All rights reserved.