TSQL: Join columns, but rows in one column have multiple values

人盡茶涼 提交于 2019-12-24 06:36:48

问题


I have a query where I have to join two tables. Lets say T1 and T2. T1 has a column with an Id. And every row has only one Id value. However, the second table is where i'm struggling. in T2 there is a column with the Id's but it can be possible that one row has multiple of those Id's. So as example T1.col1 has this value: 737382. But T2.col2 can have this entries in one row: 737382;239112;2838210;9923834;2388342;...

I know that this structure violates the 1NF and stuff. But i cannot change anything in the data or structure of the data. now what i want to do is to join this two tables. Please let me know if i'm missing to tell any relevant information in order to answer my question. its late and my brain is exhausted ~.~


回答1:


try

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

the extra affixed ; characters serve to avoid disjunctions in the join condition.




回答2:


You could use regular expressions in your join, your regular expression can check for your T1.col1 in T2.col2. The regular expression should check for the value from the begining of the string (i.e. T2.col2) or being preceeded by ';' and always followed by ';'




回答3:


Have you tried something like:

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



回答4:


Since one T2.Col2 can hold n entries, you need to parse them to rows using a table-valued function and then using CROSS APPLY

BEWARE if the T2 is big this solution will hang for quite long time

something like this:

;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

having 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



回答5:


After using the solution of collapstar (which was correct) i encountered performance issues. so what i did is to create a mapping table so that when i have to run the query again, i dont have to wait so long. so i have a scheduled job which does the join and writes the output into a mapping table over night



来源:https://stackoverflow.com/questions/17726476/tsql-join-columns-but-rows-in-one-column-have-multiple-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!