一尘不染

(递归)SQL查询而不是循环

sql

我正在寻找一个查询以获取以下输出:

Id Number
-- ------
 1 241100
 2 241110
 2 241111
 2 241112
 2 241113
 2 241114
 2 241115

表结构:

Id Number From To
-- ------ ---- ----
 1 241100 NULL NULL
 2 241110  111  115

没有从/到范围的行必须返回数字。其他人必须返回数字,后跟SUBSTRING(Number, 1, 3) + <from/to range>

一种可能的解决方案是使用while循环。但这不是我想要的方式。而且相当慢。而且没有办法改变数据结构。我们查询来自第三方供应商的数据。


在应用程序站点上,我有一个(很小的)数字列表,例如“ 241113”,“ 241000”,…,并且需要知道该数字分配给哪个ID。

我将用来获得结果的查询是:

SELECT Id, Number FROM MyView WHERE Number IN ('241113', '241000')

阅读 216

收藏
2021-05-23

共1个答案

一尘不染

我将用来获得结果的查询是:

从MyView WHERE编号输入中选择编号(‘241113’,‘241000’)

这就是您可以编写该查询的方式。无需生成数字。

declare @T table
(
  Id int,
  Number int,
  [From] int,
  [To] int
)

insert into @T values
(1, 241100, NULL, NULL),
(2, 241110,  111,  115)

select T.Id, V.Number
from @T as T
  inner join (values (241113), 
                     (241100)) as V(Number)
    on V.Number between T.Number and T.Number + isnull(T.[To], 0)

您将要查找的数字放在表变量中的版本。

declare @V table(Number int)
insert into @V values(241100)
insert into @V values(241113)

select T.Id, V.Number
from @T as T
  inner join @V as V
    on V.Number between T.Number and T.Number + isnull(T.[To], 0)

我没有在From任何地方使用过,因为我不清楚除null和之外该列中可能有哪些值number+1

还有一个版本,您可以在生成编号之前先将其过滤掉。结果是一样的,我相信效果并不理想。

;with C as
(
  select T.Id,
         T.Number
  from @T as T
  union all
  select T.Id,
         C.Number + 1
  from @T as T
    inner join C
      on C.Id = T.Id
  where stuff(C.Number, 1, 3, '') < T.[To]
)
select Id, Number
from C
where Number in ('241113', '241100')
2021-05-23