产品数字操作的序列号|数据库设计

问题描述:

所以在我的数据库中,我得到了表产品数字操作的序列号|数据库设计

Product (prodId,Name,Price) 
Box (BoxId,prodId,From,To,Available) 

From”代表第一个序列号。和'To'结束序列。 计算'To'子'From'给出的数量为products

客户来了一个给定数量的给定产品的订单。我需要的是给出'From'序列号,我计算'From'+数量。 如果序列号只是顺序整数。这很容易。但是这适用于具有不同序列号的所有类型的产品。 对于前:

Box(1,1,ABC00000C,ABC00099K,100) 

我想实现的是:

SELECT From + 50 FROM BOX 

我该怎么处理的序列号来获得结束序号顺序?

+0

尝试用SQL编写你想完成的任务。 – wast

+0

已更新 – Wildfire

+0

为什么来自和来自不同的最后一个字母?不应该只是数字有所不同吗?另外,您能否提供更多关于您正在处理的不同序列号的例子? – wast

要处理此类序列号,您需要(选项1)fn(x)计算给定整数x的序列号,或者(可选序列号2)列表(可选序列号)。

选项1最容易实现,但它需要思考序列号格式的人确实想到了构成一个转换公式以将整数转换为序列号。如果存在这样的公式,则只需确定“from”值的整数值,将50加到此整数值“x”并确定“x + 50”的序列号。

选项2要求您有一个列表,或者可以生成一个序列号列表,并且这些序列号必须(以某种方式)按逻辑顺序排列。然后,选项2应用SQL服务器提供的许多方法之一,从该列表中获取下一行50行,从具有值“From”的行开始。这种方法的例子是“select top(50)...”,窗口函数“row_number()over(order by ...)”,“select ... order by ... offset n rows fetch fetch next 50 rows only “甚至是一个光标。

评论后添加的野火:

我建议你创建一个表保持连续的选项2.让我给一个例子来说明这一点:你会怎么做,如果用串行N一个项目+ 5恰巧生产线已经倒下,损坏无法修复?即这一个序列号将永远不会被运送给客户。我敢打赌,在这种情况发生时,你不会装运一个装有少一件物品的箱子,也不会丢弃49件完好无损的产品,因为一件物品丢失了。相反,您可能会将序列号为n的所有产品放入n + 4和n + 6到n + 51的盒子中,而将序列号n + 5留出。在一个完美的世界中,这当然不会发生,但在现实生活中,事情有时会出错,所以你需要能够应付 - 例如 - 缺少连续剧。所以我真的建议创建一个所有可用于拳击的连续剧的表格,并且简单地让您的拳击过程从该表格中读取下50个连续剧。

即使串行本身是非数值的,但可以计算为数值,选项1也可以工作。这只是更复杂一点。这就是为什么我说为该方法工作的连续出版物必须存在一个公式。下面是一个例子,你可以如何添加50到串行“ABC00000C”,使“ABC00001Y”到串行:

declare @from varchar(9) = 'ABC00000C'; 

declare @from_int bigint; 

with cteSerialCharacters as (
    -- The set of characters used in a serial. 
    -- As an example I've taken all number characters plus 
    -- all capital letters from the alphabet excluding any 
    -- of these that are easily misread. 
    select 'ABCDEFGHJKLMNPRSTVWXYZ' as chars 
), 
cteNumberGenerator as (
    select cast (row_number() over (order by (select null)) as bigint) as n 
    from (select 1 union all select 1 union all select 1 union all select 1 
      union all select 1 union all select 1 union all select 1 
      union all select 1 union all select 1 
     ) t (xyz) 
) 
select 
    @from_int = sum(power(s.base, (n - 1)) * (-1 + charindex(substring(reverse(s.serial), n.n, 1), s.characterset))) 
from (
     select 
      @from, 
      cast(len(ch.chars) as bigint), 
      ch.chars 
     from cteSerialCharacters ch 
    ) s (serial, base, characterset) 
    inner join cteNumberGenerator n on (n.n <= len(s.serial)); 


select @from, @from_int; 

declare @to varchar(9); 
declare @to_int bigint; 


select @to_int = @from_int + 50; 


with cteSerialCharacters as (
    -- The set of characters used in a serial. 
    -- As an example I've taken all number characters plus 
    -- all capital letters from the alphabet excluding any 
    -- of these that are easily misread. 
    select 'ABCDEFGHJKLMNPRSTVWXYZ' as chars 
), 
cteNumberGenerator as (
    select cast (row_number() over (order by (select null)) as bigint) as n 
    from (select 1 union all select 1 union all select 1 union all select 1 
      union all select 1 union all select 1 union all select 1 
      union all select 1 union all select 1 
     ) t (xyz) 
) 
select 
    @to = (
      select 
       substring(s.characterset, 1 + (@to_int/power(s.base, n.n - 1)) % s.base, 1) as [text()] 
      from (
        select 
         cast(len(ch.chars) as bigint), 
         ch.chars 
        from cteSerialCharacters ch 
       ) s (base, characterset) 
       cross join cteNumberGenerator n 
      order by n.n desc 
      for xml path(''), type 
     ).value('text()[1]', 'varchar(9)') 

select @to, @to_int; 
+0

选项2不能完成。我没有一个清单,但有两个连续出版物:“From”和“To”。选项1仅适用于串行是一个顺序整数。就像我在之前的文章中所说的。如果给定的序列是“AB5C-0005B”。接下来的10个连续剧会是什么? – Wildfire

+0

@Wildfire:当然两种选择都是可能的,选项2是可取的。我会通过添加我的答案来解释。 – rrozema

+0

这是假定串行中的所有字符都可以是字母数字。如果是这样,使用base36方法添加将非常容易。所以我的问题是:是否有任何产品序列在最后有一个字母,但这只能是具体的。例如,5个系列是:“ABC000A”,“ABC000B”“ABC001A”“ABC001B”“ABC002A”? – Wildfire