1

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

我有以下 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
4

5 回答 5

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

于 2013-03-12T16:25:21.767 回答
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.

于 2013-03-12T16:28:24.517 回答
2

我已经发布了一个我没有测试过但应该可以工作的解决方案。这样做感觉不对,我现在通过回答鼓励你感到不干净:

SELECT tbl1.CompId, tbl2.Id
FROM tbl1  
  JOIN tbl2 ON CommaList LIKE '%''' + CAST(tbl2.ClientId AS VARCHAR) + '%''' 
于 2013-03-12T16:28:45.810 回答
1

试试这个:

select tbl1.CompId, tbl2.Id
from tbl1, tbl2 
where CHARINDEX('''' + CONVERT(varchar(50),tbl2.ClientId) + '''', CommaList)<> 0
于 2013-03-12T16:26:09.317 回答
0

如果由于某种原因您不能使用Char Indexorlike解决方案,您可以拆分逗号列表然后加入。例如,如果您需要做概念上的等价物

从 CommaList 上的 tbl2 = tbl2.ClientId LEFT join tbl1 join

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

演示

笔记:

  • 我没有费心处理引号分隔的部分,但你可以很容易地做到这一点replace(commalist,'''','')
  • 照原样,这仅适用于长度 <= 2047 的 commalist 值。如果您正在处理更大的列表,您可以在此答案中使用GarethD 的第二个示例来生成更大的数字表
于 2013-03-12T19:28:16.110 回答