TSQL:连接列,但一列中的行具有多个值

时间:2013-07-18 14:35:32

标签: sql-server-2008 tsql join rows

我有一个查询,我必须加入两个表。让我们说T1和T2。 T1有一个带有Id的列。每行只有一个Id值。然而,第二张桌子是我在努力的地方。在T2中有一个带有Id的列但是有一行可能有多个Id。 因此,例如T1.col1具有此值:737382.但是T2.col2可以在一行中包含此条目:737382; 239112; 2838210; 9923834; 2388342; ...

我知道这种结构违反了1NF和东西。但我不能改变数据的数据或结构。 现在我想要做的是加入这两个表。如果我不想告诉任何相关信息以便回答我的问题,请告诉我。它迟到了,我的大脑筋疲力尽~~~

5 个答案:

答案 0 :(得分:0)

尝试

    select tab2.*   -- whatever
      from t1 tab1
inner join t2 tab2 on ( ';'||tab2.col2||';' like '%;'||tab1.col1||';%' )
         ;

额外加;个字符用于避免连接条件中的脱节。

答案 1 :(得分:0)

你有没有试过像:

select 
    a.column1, 
    a.column2, 
    b.column1,
    b.column2 
from table a 
inner join table b on a.column1 = b.column1

答案 2 :(得分:0)

您可以在加入中使用正则表达式,正则表达式可以检查T1.col1中的T2.col2。正则表达式应检查字符串开头的值(即T2.col2)或';'之前的值,并始终跟';'

答案 3 :(得分:0)

由于一个T2.Col2可以容纳 n个条目,您需要使用表值函数将它们解析为行,然后使用CROSS APPLY

注意如果T2很大,这个解决方案会挂起很长时间

类似的东西:

;WITH IDSplitted AS 
(
   SELECT * 
   FROM  T2
   CROSS APPLY dbo.[StringSplit](col2, ';')
)

SELECT * -- or whatever columns you need
FROM T1
INNER JOIN IDSplitted  ON IDSplitted.val = t1.col1

拥有StringSplit:

CREATE FUNCTION [dbo].[StringSplit]
(
  @delimited nvarchar(max),
  @delimiter nvarchar(100)     
) RETURNS @t TABLE
(
-- Id column can be commented out, not required for sql splitting string
  id int identity(1,1), -- I use this column for numbering splitted parts
  val nvarchar(max)
)
AS
BEGIN
  declare @xml xml
  set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'

  insert into @t(val)
  select 
    r.value('.','varchar(max)') as item
  from @xml.nodes('//root/r') as records(r)

  RETURN
END

答案 4 :(得分:0)

使用collapstar解决方案(这是正确的)后,我遇到了性能问题。所以我所做的是创建一个映射表,以便当我必须再次运行查询时,我不必等待这么久。所以我有一个预定的工作,它会进行连接并将输出写入映射表中过夜