2012-08-13 94 views
0

这听起来像一个问题,应该在我考上大学的考试中,但我向你保证这是我试图解决的现实世界问题......并且我不是一个真正的SQL专家。假设我销售相机(虚构),并且每台相机都有自己的[前缀] - [数字]格式的唯一序列号。我们在更换固件或更换新电脑芯片时会更改前缀。相机具有3年的MFG保修期,因此我们试图给我们的经销商提供序列号,以表示“任何序列号在J05之下的相机-123456可能已经太旧了,请将其发回“SQL字符串解析,然后按日期块排序和排序

问题是,我们依次生产相机,但随后50台相机将坐在我们仓库的货架上,并且运输人员将随机抓取并运送所以它们是半顺序销售的,但是可能会有大量的异常值,其中几个单位被搁置了几个月后才卖出。

大约有1000万连续剧。任何好方法来完成这个?

 
Serial  | Sale Date 
J22-521253 | 7/2/12 
J22-521254 | 6/28/12 
J22-521255 | 6/28/12 
J22-521256 | 7/1/12 
J22-521257 | 6/22/12 
J22-521258 | 7/4/12 
J22-521259 | 7/1/12 
J22-521260 | 6/27/12 
J22-521261 | 6/25/12 
J22-521262 | 6/20/12 
J22-521263 | 8/30/12 
J22-521264 | 6/30/12 
J22-521265 | 6/30/12 
Y7-542127 | 5/1/12 
Y7-542128 | 4/18/12 
Y7-542129 | 4/22/12 
Y7-542130 | 1/10/12 
+0

对于1000万行,不会有这样做的有效方式,对不起。无论您使用CHARINDEX等进行什么样的技巧,子串匹配和数据类型转换都将导致1000万行的表扫描。 – 2012-08-13 18:05:33

+0

可能要添加前缀列并在其上添加索引。要获得前缀: SELECT LEFT(Serial,CHARINDEX(Serial,' - ') - 1) – Jim 2012-08-13 18:07:53

+0

我假设您要将查询放入应用程序。实现这一目标的一种方法是将数据集实现为夜间工作的一部分,以创建一个只有前缀和第一个序列号在一定范围内的较小表格。你可以在前缀上索引,它会超快。 – 2012-08-13 18:13:36

回答

0

我在解释这个问题,说你想让每个前缀的最早序列号仍在保修期内。任何旧的会太旧。

请澄清问题,如果不是这种情况。

select prefix, salesdate, serial 
from (select left(serial, 3) as prefix, 
      row_number() over (partition by prefix order by salesdate) as seqnum 
     from (select t.*, left(serial, 3) as prefix 
      from t 
      where datediff(days, salesdate, CURRENT_TIMESTAMP) < 3*365.25 
      ) t 
    ) t 

这使用row_number()来查找仍在保修期内的最早序列。