Sql server 2008 如何在SQL Server 2008 R2中不使用游标填充表

Sql server 2008 如何在SQL Server 2008 R2中不使用游标填充表,sql-server-2008,cursor,while-loop,Sql Server 2008,Cursor,While Loop,我需要识别丢失的产品,这些产品的编号是连续的。换句话说,我们的每个商店都有一套产品,每种产品都有一个唯一的编号。最终用户需要一个报告,该报告将识别日期范围内缺少的小部件 Store Product Number Store 1 Widget 100 Store 1 Widget 101 Store 1 Widget 102 Store 1 Widget 104 Store 2 Widget 201 Store 2 Widget 202 Store 2 W

我需要识别丢失的产品,这些产品的编号是连续的。换句话说,我们的每个商店都有一套产品,每种产品都有一个唯一的编号。最终用户需要一个报告,该报告将识别日期范围内缺少的小部件

Store   Product Number
Store 1  Widget   100
Store 1  Widget   101
Store 1  Widget   102
Store 1  Widget   104
Store 2  Widget   201
Store 2  Widget   202
Store 2  Widget   203
我认为最好的方法是获取MAXNumber和MINNumber,然后用序列中的所有数字填充一个表变量。如果表变量中的小部件编号在产品表中不存在,我将返回该编号并将其标记为缺失

但是,;我们的DBA非常反对游标,我知道循环会占用大量开销。另外,我不知道如何在分店的基础上做到这一点

有人知道如何以基于集合的方式实现这一点吗

小部件本身有编号,所以当您销售小部件1时,您销售的下一个小部件应该是小部件2。然而有时,这种情况不会发生,小部件3被出售——小部件2丢失,不在数据库中。我需要在一份报告中确认小部件1和3已经售出,而小部件2已经丢失。

更新了答案

下面是创建表和工作解决方案的示例代码。基本上,您需要进行两次检查,以查看是否有数字高于当前数字,并且没有数字高于当前数字

DECLARE @t Table (Store int, Product varchar(100), number int)
INSERT INTO @t
VALUES
(1, 'Widget',   100),
(1, 'Widget',   101),
(1, 'Widget',   102),
(1, 'Widget',   104),
(2, 'Widget',   201),
(2, 'Widget',   202),
(2, 'Widget',   203)

SELECT Store, Product, t.Number+1 as Missing
FROM @t t
WHERE EXISTS (SELECT 1 FROM @t t2
              WHERE t2.Store = t.Store
              AND t2.product = t.product
              AND t2.number > t.number)
AND Not Exists (SELECT 1 FROM @t t3
                WHERE t3.Store = t.store
                AND t3.product = t.product
                AND t3.number = t.number + 1)
最新答案

下面是创建表和工作解决方案的示例代码。基本上,您需要进行两次检查,以查看是否有数字高于当前数字,并且没有数字高于当前数字

DECLARE @t Table (Store int, Product varchar(100), number int)
INSERT INTO @t
VALUES
(1, 'Widget',   100),
(1, 'Widget',   101),
(1, 'Widget',   102),
(1, 'Widget',   104),
(2, 'Widget',   201),
(2, 'Widget',   202),
(2, 'Widget',   203)

SELECT Store, Product, t.Number+1 as Missing
FROM @t t
WHERE EXISTS (SELECT 1 FROM @t t2
              WHERE t2.Store = t.Store
              AND t2.product = t.product
              AND t2.number > t.number)
AND Not Exists (SELECT 1 FROM @t t3
                WHERE t3.Store = t.store
                AND t3.product = t.product
                AND t3.number = t.number + 1)

创建一个数字表,并用超出需要的数字填充它。 然后可以使用基于集合的查询来获得结果

Create table #temp (product varchar(15), id int)
insert into #temp
values ('test', 1), ('test', 3),('test', 4),('test2', 6),('test2', 2),('test2', 10),('test3', 10),('test3', 9),('test3',7),('test4', 1),('test4', 2),('test4', 3)

create table #product (product varchar (15))
insert into #product 
values ('test'),('test2'),('test3'),('test4'), ('test5')
create table #num (number int)

insert into #num
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)

select n.number,p.product from #num n
cross join #product p 
left join (
select product, max(id)as maxid from #temp group by product)a
on a.product = p.product 
left join #temp t on n.number = t.id and t.product = p.product
where  n.number <=a.maxid and t.id is null
order by p.product

创建一个数字表,并用超出需要的数字填充它。 然后可以使用基于集合的查询来获得结果

Create table #temp (product varchar(15), id int)
insert into #temp
values ('test', 1), ('test', 3),('test', 4),('test2', 6),('test2', 2),('test2', 10),('test3', 10),('test3', 9),('test3',7),('test4', 1),('test4', 2),('test4', 3)

create table #product (product varchar (15))
insert into #product 
values ('test'),('test2'),('test3'),('test4'), ('test5')
create table #num (number int)

insert into #num
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)

select n.number,p.product from #num n
cross join #product p 
left join (
select product, max(id)as maxid from #temp group by product)a
on a.product = p.product 
left join #temp t on n.number = t.id and t.product = p.product
where  n.number <=a.maxid and t.id is null
order by p.product

您的DBA不能帮助您使用基于集合的解决方案吗?解雇DBA!上周有人告诉我,我们的DBA太忙了,无法回答问题,我需要利用自己的SQL知识在没有他的帮助下开发这些报告。顺便说一句,不是DBA,而是我的老板。你有一个DBA不能帮助你解决基于集合的解决方案吗?解雇DBA!上周有人告诉我,我们的DBA太忙了,无法回答问题,我需要利用自己的SQL知识在没有他的帮助下开发这些报告。顺便说一句,不是DBA,而是我的老板。我想我没有很好地解释我的问题。小部件本身有编号,所以当您销售小部件1时,您销售的下一个小部件应该是小部件2。然而有时,这种情况不会发生,小部件3被出售-小部件2丢失并且不在数据库中。@DataGirl-ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。给我一分钟时间发布一个解决方案。这很好,除了一个小问题。使用真实数据,我知道我缺少5228和5229,但5228出现了两次。如果丢失的数据导致数字之间的差距超过一,我该怎么办?而且,非常感谢你在这方面帮助我@DataGirl-你可以通过一个联合来扩展它。例如,当前查询、UNION,然后在select和子查询中使+1成为+2。这有点骇人听闻,但它会起作用。我想我没有充分解释我的问题。小部件本身有编号,所以当您销售小部件1时,您销售的下一个小部件应该是小部件2。然而有时,这种情况不会发生,小部件3被出售-小部件2丢失并且不在数据库中。@DataGirl-ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。给我一分钟时间发布一个解决方案。这很好,除了一个小问题。使用真实数据,我知道我缺少5228和5229,但5228出现了两次。如果丢失的数据导致数字之间的差距超过一,我该怎么办?而且,非常感谢你在这方面帮助我@DataGirl-你可以通过一个联合来扩展它。例如,当前查询、UNION,然后在select和子查询中使+1成为+2。这很粗糙,但会有用的。