我有一个包含数字的字段,例如下面#Numbers中的示例。 #Numbers中每行中的每个数字都相关 包含在#Area表中的许多不同值中。
我需要使用每一行中的每个数字来建立从#Numbers到#Area的关系。
CREATE TABLE #Numbers
(
Number int
)
INSERT INTO #Numbers
(
Number
)
SELECT 102 UNION
SELECT 1 UNION
SELECT 2 UNION
select * from #Numbers
CREATE TABLE #Area
(
Number int,
Area varchar(50)
)
INSERT INTO #Area
(
Number,
Area
)
SELECT 0,'Area1' UNION
SELECT 1,'Area2' UNION
SELECT 1,'Area3' UNION
SELECT 1,'Area5' UNION
SELECT 1,'Area8' UNION
SELECT 1,'Area9' UNION
SELECT 2,'Area12' UNION
SELECT 2,'Area43' UNION
SELECT 2,'Area25' UNION
select * from #Area
它将为102返回以下内容:
102,Area2
102,Area3
102,Area5
102,Area8
102,Area9
102,Area1
102,Area12
102,Area43
102,Area25
对于1,它将返回:
1,Area2
1,Area3
1,Area5
1,Area8
1,Area9
对于2,它将返回:
2,Area12
2,Area43
2,Area25
请注意数字如何与各个区域匹配,并相应地返回值。
答案 0 :(得分:3)
好吧,OP已经标记了一个答案,甚至得到了投票。也许他不会读这本书,但是这是使用直接简单选择的另一种选择,(根据EP),这似乎使用了很多资源:
SELECT *
FROM #Numbers t1
LEFT JOIN #Area t2 ON CONVERT(VARCHAR(10), t1.Number) like '%' + CONVERT(CHAR(1), t2.Number) + '%'
GO
注意!根据执行计划,此解决方案仅使用27%,而选定的答案(由Squirrel编写)使用73%,但是执行计划有时会误导您, 您还应该使用真实的表结构和真实的数据检查IO和TIME统计信息。
答案 1 :(得分:2)
看来您需要从#Number
中提取单个数字,然后将其用于加入#Area
; with tally as
(
select n = 1
union all
select n = n + 1
from tally
where n < 10
)
select n.Number, a.Area
from #Numbers n
cross apply
(
-- here it convert n.Number to string
-- then extract 1 digit
-- and finally convert back to integer
select num = convert(int,
substring(convert(varchar(10), n.Number),
t.n,
1)
)
from tally t
where t.n <= len(convert(varchar(10), n.Number))
) d
inner join #Area a on d.num = a.Number
order by n.Number
或者,如果您更喜欢用算术而不是字符串
; with Num as
(
select Number, n = 0, Num = Number / power(10, 0) % 10
from #Numbers
union all
select Number, n = n + 1, Num = Number / power(10, n + 1) % 10
from Num
where Number > power(10, n + 1)
)
select n.Number, a.Area
from Num n
inner join #Area a on n.Num = a.Number
order by n.Number
答案 2 :(得分:0)
这是我的主意。从理论上讲,它应该起作用。 有一个带有值的表(临时表或永久表)及其转换
IE。
ID value
1 Area1, Area2, Area7, Area8, Area15
2 Area28, Area35
等
在每一行中各加一个特殊字符。使用带有该字符的string_split之类的函数将其转换为值列。
例如0123将类似于0 | 1 | 2 | 3,当您通过string_split运行它时,您将得到
0
1
2
3
现在将每个值添加到您的查询表中并返回值。
现在您有了一行,其中包含所需的所有值。使用另一个函数,例如STUFF FOR XML,并将这些值放回到单列中。
这听起来效率不高..但这是实现您所期望的一种方法..
另一种方法是进行replace()
..但这很混乱!
答案 3 :(得分:0)
创建第三个表n,该表包含一个列,也称为n,该列包含从1到您的数字中最大位数的整数。如果愿意,将其设置为1000,没关系。然后:
select #numbers.number, substring(convert(varchar,#numbers.number),n,1) as chr, Area
from #numbers
join n on n>0 and n <=len(convert(varchar,number))
join #area on #area.number=substring(convert(varchar,#numbers.number),n,1)
中间的一栏chr只是在这里向您展示它在做什么,并且将从最终结果中删除。