用于列的开始和结束的SQL查询

时间:2014-09-06 13:26:50

标签: sql sql-server-2008-r2

我正在尝试编写查询以获取特定销售的开始和结束序列

Serial    Sale_id
0001      1
0002      1
0003      1
0004      2
0005      2
0006      1
0007      1
0008      1

我正在寻找像

这样的结果
Quantity     Start    End
3            0001     0003
3            0006     0008

有人可以帮我把这个弄好吗

2 个答案:

答案 0 :(得分:2)

此查询(改编自本书SQL MVP Deep Dives)应该可以为您提供所需内容:

SELECT 
  Sale_id, --optional, include is you want the Sale_id

  -- if Serial is a (VAR)CHAR type use this field
  Quantity = MAX(CAST(Serial AS INT)) - MIN(CAST(Serial AS INT)) + 1, 

  -- if Serial is INT already use this field instead
  --Quantity = MAX(CAST(Serial AS INT)) - MIN(CAST(Serial AS INT)) + 1, 

  [Start] = MIN(Serial), 
  [End] = MAX(Serial)

FROM (
  SELECT 
    Sale_id, 
    Serial,
    RowNumber = 
      Serial - ROW_NUMBER() OVER (PARTITION BY Sale_id ORDER BY Serial)
  FROM YourTable
  ) a
--WHERE Sale_id = 1 -- optional limiting WHERE clause
--WHERE Sale_id IN (1,2) -- optional limiting WHERE clause
GROUP BY Sale_id, RowNumber
ORDER BY Start;

我假设Serial存储为字符类型并包含对INT的强制转换。如果它已经是数字类型,请更改为没有Quantity的强制转换的行。

我选择在输出中加入Sale_id列,如果您不想要它,只需将其注释掉即可。如果您希望将结果限制为一个或多个特定Sale_id,请包含WHERE子句中的一个。

Sample SQL Fiddle

示例输出:

Sale_id     Quantity    Start      End
----------- ----------- ---------- ----------
1           3           0001       0003
2           2           0004       0005
1           3           0006       0008

(3 row(s) affected)

答案 1 :(得分:1)

您可以通过在每个销售ID之前计算非类似销售ID的数量来实现此目的。对于销售ID相同的序列,这是常量。然后使用它进行分组:

select count(*), min(serial_no), max(serial_no)
from (select t.*,
             (select count(*)
              from taple  t2
              where t2.serial_no <= t.serial_no and
                    t2.sale_id <> t.sale_id
             ) as grp
      from taple  t
     ) t
group by grp;

如果您只关心sale_id = 1,那么在中间子查询查询中添加where子句。

Here是一个SQL小提琴。