0

我有一个带有 char(5) 字段的表,用于跟踪 Bin 编号。数字以前导零存储。这些数字从 00200 到 90000。已经使用的数字有很多空白,我需要能够查询它们,以便用户知道哪些数字可以使用。

4

2 回答 2

0

通过阅读Pinal Dave的这篇文章,我能够得到我所需要的东西

我创建了一个存储过程,它返回从第一个 bin 编号到最后一个 bin 编号序列中的间隙。在我的应用程序中,我按商店(车辆从 1000 到 2000,建筑物从 2001 到 3000 等)对箱号进行分组。

ALTER PROCEDURE [dbo].[spSelectLOG_BinsAvailable]

(@Shop varchar(9))
AS
BEGIN
declare @start as varchar(5) = (SELECT b.Start FROM BinShopCodeBlocks b WHERE b.Shop = @Shop)
declare @finish as varchar(5) = (SELECT b.Finish FROM BinShopCodeBlocks b WHERE b.Shop = @Shop)

SET NOCOUNT ON;

WITH CTE 
AS
(SELECT
        CAST(@Start as int) as start,
        cast(@Finish as int) as finish

UNION ALL
SELECT
        Start + 1,
        Finish

FROM
        CTE
WHERE
        Start < Finish
)

SELECT
    RIGHT('00000' + CAST(Start AS VARCHAR(5)), 5)
FROM CTE  
WHERE
NOT EXISTS
        (SELECT *
         FROM
         BinMaster b
         WHERE
         b.BinNumber  = RIGHT('00000' + CAST(Start AS VARCHAR(5)), 5)
        )
OPTION (MAXRECURSION 0);


END
于 2013-07-23T23:08:30.480 回答
0

假设您有一个有效的 bin 编号表。

Table: bins

bin_num
--
00200
00201
00202
...
90000

假设您的表名为“库存”。此查询返回的箱号是不在“库存”中的箱号。

select bins.bin_num
from bins
left join inventory t2
       on bins.bin_num = t2.bin_num
where t2.bin_num is null
order by bins.bin_num

如果您的 SQL Server 版本支持分析函数(并且仅为方便起见,还支持公用表表达式),那么您可以找到大多数这样的差距。

with bin_and_next_bin as (
  select bin, lead(bin) over (order by bin) next_bin
  from inventory
)
select bin
from bin_and_next_bin 
where cast(bin as integer) <> cast(next_bin as integer) - 1

分析函数不需要有效的 bin 编号表,尽管您可以提出一个非常有力的案例,即您应该首先拥有这样的表。如果您在没有此类表的环境中工作,并且不允许构建此类表,则通用表表达式可以节省一天的时间。(不过,它不会在第一个使用的 bin 编号之前显示“丢失的”bin 编号,因为它是在这里写的。)

该语句的另一个缺点是 WHERE 子句不是 sargable。它不能使用索引。还有一个是它假设 bin 编号可以转换为整数。基于表的方法不假设 bin 编号的值或数据类型。它适用于混合字母数字,就像它适用于整数或其他任何东西一样。

于 2013-07-22T18:07:57.280 回答