(串行列)过滤SQL查询并将结果缩短为Range

时间:2012-10-09 06:08:38

标签: sql sql-server tsql sql-server-2000

例如,我有列表pallet_id和serial

我想从

查询它们
pallet_id       serial 
PA1             161
PA1             163
PA1             164
PA1             165
PA1             166
PA1             177
PA1             178
PA1             179

pallet_id       serial 
PA1             161-161
PA1             163-166
PA1             177-179

序列加1需要坚持作为范围组

我现在只使用视图。如果有其他方法可以执行此操作而不会导致存储过程,请提示。

我正在开发SP,因为我找不到另一种方式。

使用MSSQL2000或更低版本.. 6.5?正如它在这里所说..所以这个SQL版本中没有函数。升级也不是一种选择。

2 个答案:

答案 0 :(得分:4)

create table #T
(
  ID int identity,
  pallet_id varchar(8),
  serial int
)

insert into #T(pallet_id, serial)
select pallet_id, serial
from YourTable
order by pallet_id, serial

select pallet_id, min(serial) min_serial, max(serial) max_serial
from #T
group by pallet_id, serial - ID

drop table #T

SQL Fiddle

答案 1 :(得分:-2)

就我个人而言,我并不喜欢将数据压缩在一起,如你所示(161-161)。它是前端的一个功能,用于呈现数据以供显示。下面的查询返回单独列中的原始范围,但如果你真的需要,它很容易组合起来。

此处的解决方案适用于SQL Server 2005及更高版本,它可以真正开始被视为“现代”。它使用的技术是通过将行位置与id进行差分来进行分组。顺序范围与ID等距,因此很好地组合在一起。

要在SQL Server 6.5(!!)中实现相同的结果,您必须通过#temp表来管理它,在INSERT..SELECT..ORDER BY语句中使用ORDERING GUARANTEE将行编号生成为Michael has shown(只需将对@T的引用更改为#T)。

-- sample table for discussion
create table tbl (
  pallet_id varchar(10),
  serial bigint);
insert tbl values
  ('PA193876',157029161),
  ('PA193876',157029163),
  ('PA193876',157029164),
  ('PA193876',157029165),
  ('PA193876',157029166),
  ('PA193876',157029177),
  ('PA193876',157029178),
  ('PA193876',157029179);

-- the query
select pallet_id, min(serial) serial_from, max(serial) serial_to
from
(
  select pallet_id, serial, grp = serial - row_number() over (order by serial)
  from tbl
) X
group by pallet_id, grp
order by pallet_id, serial_from;

-- the results
PALLET_ID   SERIAL_FROM SERIAL_TO
PA193876    157029161   157029161
PA193876    157029163   157029166
PA193876    157029177   157029179

e.g。 right(min(serial),10) + ' - ' + right(max(serial),10) serial_range