表1:
A B C
Test 1 This
Test1 1;4 That
Test2 7 What
Test3 6;2 Which
Test4 1;2;7 Where
表2:
X Z
1 Sun
2 Mon
3 Tue
4 Wed
5 Thu
6 Fri
7 Sat
SQL:
Select
t1.A,
t2.Z
from
[dbo].[Table 1] t1
inner join [dbo].[Table2] t2
on t1.B = t2.X
它仅适用于B
列中只有1个条目但在2个或更多条目中失败的行。
如何修改Sql,以便它给我这样的结果:
A Z
Test Sun
Test1 Sun;Wed
Test2 Sat
Test3 Fri;Mon
Test4 Sun;Mon;Sat
答案 0 :(得分:1)
你真的不应该在同一列中存储多个值,只有在你真正需要对这些值做某事时才会导致性能不佳。
使用Jeff Moden的CSV Splitter表值函数并使用stuff()
with select ... for xml path ('')
method of string concatenation。 :
select
t1.a
, z = stuff((
select ';'+t2.Z
from t1 i
cross apply dbo.delimitedsplit8K(i.b,';') s
inner join t2
on s.Item = t2.x
where i.a = t1.a
order by s.ItemNumber
for xml path(''),type).value('(./text())[1]','nvarchar(max)')
,1,1,'')
from t1
rextester 演示:
返回:http://rextester.com/HNNP95095
+-------+-------------+
| a | z |
+-------+-------------+
| Test | Sun |
| Test1 | Sun;Wed |
| Test2 | Sat |
| Test3 | Fri;Mon |
| Test4 | Sun;Mon;Sat |
+-------+-------------+
拆分字符串参考:
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand <小时/> Jeff Moden的功能用于演示:
create function [dbo].[delimitedsplit8K] (
@pstring varchar(8000)
, @pdelimiter char(1)
)
returns table with schemabinding as
return
with e1(N) as (
select 1 union all select 1 union all select 1 union all
select 1 union all select 1 union all select 1 union all
select 1 union all select 1 union all select 1 union all select 1
)
, e2(N) as (select 1 from e1 a, e1 b)
, e4(N) as (select 1 from e2 a, e2 b)
, ctetally(N) as (
select top (isnull(datalength(@pstring),0))
row_number() over (order by (select null)) from e4
)
, ctestart(N1) as (
select 1 union all
select t.N+1 from ctetally t where substring(@pstring,t.N,1) = @pdelimiter
)
, ctelen(N1,L1) as (
select s.N1,
isnull(nullif(charindex(@pdelimiter,@pstring,s.N1),0)-s.N1,8000)
from ctestart s
)
select itemnumber = row_number() over(order by l.N1)
, item = substring(@pstring, l.N1, l.L1)
from ctelen l
;
go
答案 1 :(得分:1)
使用字符串和XML的乐趣,这是一种用于标记数据的小(缩小)技术。
创建一些示例数据
Declare @Table1 table (A varchar(100),B varchar(100), C varchar(100))
Insert Into @Table1 values
('Test','1','This'),('Test1','1;4','That'),('Test2','7','What'),('Test3','6;2','Which'),('Test4','1;2;7','Where')
Declare @Table2 table (X int,Z varchar(100))
Insert Into @Table2 values
(1,'Sun'),(2,'Mon'),(3,'Tue'),(4,'Wed'),(5,'Thu'),(6,'Fri'),(7,'Sat')
SQL
Declare @XML xml,@Str varchar(max) = (Select a,z='['+replace(b,';','];[')+']' From @Table1 For XML Raw)
Select @Str = Replace(@Str,'['+cast(X as varchar(25))+']',Z) From @Table2
Select @XML = @Str
Select a = r.value('@a','varchar(100)')
,z = r.value('@z','varchar(100)')
From @XML.nodes('/row') as A(r)
<强>返回强>
a z
Test Sun
Test1 Sun;Wed
Test2 Sat
Test3 Fri;Mon
Test4 Sun;Mon;Sat