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