SQL需要内部加入

时间:2013-03-12 16:20:08

标签: sql sql-server tsql

请注意,我在系统下面的内容已经存在,因此更改它需要时间。因此,我知道最好的方法是规范化,但......

我有以下2个表

Tbl1

CompId      CommaList
------      --------
2           '122','54','90'   
54          '53','76'
34          '87' 
22          '98'


Tbl2

ID     ClientId   
--     --------
1      122
2      76 
3      87
4      98

我需要的是加入Tbl1和Tbl2,然后返回CompId和ID

连接应该从tbl2.ClientId和tbl1.CommaList完成(这是一个逗号分隔的列表,我需要从中找到匹配的值。

希望这是有道理的。

    select tbl1.CompId, tbl2.Id
    from tbl1  join tbl2 on CommaList = tbl2.ClientId

显然这不会起作用,因为它们属于不同的类型,我还需要在CommaList中找到列表。

最终结果如下:

ID       CompId
--       ------
1        2 
2        54
3        34
4        22

5 个答案:

答案 0 :(得分:3)

免责声明在数据库列中存储以逗号分隔的列表是代码味道,通常表示您需要规范化数据库结构。如果可能的话,请不要在您的代码中执行此操作。


您可以通过将逗号分隔列表中的客户端ID值与LIKE子句匹配来解决:

select
  t2.ID, t1.CompId
from Tbl1 t1
join Tbl2 t2 on t1.CommaList
  like '%''' + cast(t2.ClientId as varchar(10)) + '''%'

演示:http://www.sqlfiddle.com/#!3/6d416/6

答案 1 :(得分:2)

几乎可以肯定,您希望使用连接表来扩展CommaList。也就是说,你想要一个带

的表
 Tbl3
 CompID      ClientID
 2            122
 2             54
 2             90
 54            53

某些数据库允许您将CommaList存储为数组并使用IN运算符,但这既是非标准的又是低效的。 (您也可以像mellamokb的答案那样进行字符串搜索,但请注意他的免责声明与我的相同。)现在你可以做到了

SELECT id, compID FROM Tbl3 NATURAL JOIN Tbl2;

除特殊情况外,请避免使用Tbl1等非规范化数据。

答案 2 :(得分:2)

我已经发布了一个我尚未测试但应该可行的解决方案。这样做感觉不对,我现在感到不洁,鼓励你回答:

SELECT tbl1.CompId, tbl2.Id
FROM tbl1  
  JOIN tbl2 ON CommaList LIKE '%''' + CAST(tbl2.ClientId AS VARCHAR) + '%''' 

答案 3 :(得分:1)

试试这个:

select tbl1.CompId, tbl2.Id
from tbl1, tbl2 
where CHARINDEX('''' + CONVERT(varchar(50),tbl2.ClientId) + '''', CommaList)<> 0

答案 4 :(得分:0)

如果由于某种原因您无法使用Char Indexlike解决方案,则可以拆分逗号列表然后加入。例如,如果你需要做概念等效的

  

来自逗号列表上的tbl2 = tbl2.ClientId LEFT 加入tbl1加入

with split as (

SELECT 
       CompID,
       Substring(commalist, number, Charindex(',', commalist + ',', number) 
                                    - number) 
                                                                   AS clientID 
FROM   tbl1  
       JOIN master..spt_values v 
         ON number <= Len(commalist) 
            AND Substring(',' + commalist, number, 1) = ',' 
WHERE  v.type = 'P' )

SELECT 

    split.CompId,
    split.clientID,
    tbl2.id


FROM 

  split
  LEFT JOIN tbl2 
  on tbl2.clientID = split.clientID

DEMO

注意:

  • 我没有打扰处理引号分隔部分,但你可以通过replace(commalist,'''','')
  • 轻松完成
  • 原样,这仅适用于长度为&lt; = 2047的commalist值。如果您要处理较大的列表,可以使用GarethD'sexample in this answer来生成更大的数字表