2017-03-31 81 views
3

表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 
+2

你使用什麼數據庫引擎?第二個爲什麼將多個值存儲在單個列中?這是糟糕的桌子設計。你可以改變它嗎? –

+0

我很抱歉...讓我更新我的問題。而且我知道,不幸的是這是給我們的設計。 – Si8

+1

這不適用於RDBMS。從'表2'中檢索數據,並使用更適合該問題的語言(Java,C#,C++)在內存中執行搜索和替換。 – dasblinkenlight

回答

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 
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 | 
+-------+-------------+ 

分割字符串參考:


傑夫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 
相關問題