在SQL中拆分列,然后在另一个表中查找每个列

我不确定这是否可以在SQL中使用,如果不是,我将以编程方式执行 – 但如果有办法,它会很棒。

基本上,我在一个表中有一个列,用另一个表中的ID填充,用逗号分隔 – 所以字段可能如下所示:

3,4,9

这些链接到另一个表,其中上面字段中的数字是行的主键。 在行中是一个描述,我想向用户显示而不是数字。

所以基本上,我不想向用户显示3,4,9,而是想在另一个表中查找相关描述。 这可能吗?

克里斯,

有一种方法可以在T-SQL中执行此操作,实际上非常简单。 首先,你需要创建一个像下面这样的函数…(使用基于零的“Tally”cte的全新方法,它很快,因为它不会连接任何分隔符)。

CREATE FUNCTION dbo.DelimitedSplit8KNEW --===== Created by Jeff Moden (Prototype: Testing Still in Progress) --===== Define I/O parameters ( @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 ), --10 E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100 E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000 cteTally(N) AS ( SELECT 0 UNION ALL SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E4 ) SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY tN), ItemValue = SUBSTRING(@pString,t.N+1,ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,t.N+1),0),DATALENGTH(@pString)+1)-tN-1) FROM cteTally t WHERE tN BETWEEN 0 AND DATALENGTH(@pString) AND (SUBSTRING(@pString,tN,1) = @pDelimiter OR tN = 0) ; GO 

现在,看看它是如何使用的…让我们假设你有一个带有唯一列的表和你的CSV列如下(这也构建了数据)。 我们所要做的就是用函数交叉应用原始数据,并且数据被神奇地拆分,准备与另一个表连接:

 --===== This just builds some test data -- and is not a part of the solution SELECT * INTO #TestTable FROM ( SELECT 1,'3,4,9' UNION ALL SELECT 2,'3,2,100' UNION ALL SELECT 3,'14,35,8,21,27,12' ) d (RowNum,CsvValue) ; --===== Split the data out giving the unique RowNum -- from the original data, the element position, -- the the value of the split element. You can -- join this SELECT with a table to get the other -- values. SELECT data.RowNum, split.ItemNumber, split.ItemValue FROM #TestTable data CROSS APPLY dbo.DelimitedSplit8KNEW(data.CsvValue,',') split ; 

这是输出……

 RowNum ItemNumber ItemValue ----------- -------------------- --------- 1 1 3 1 2 4 1 3 9 2 1 3 2 2 2 2 3 100 3 1 14 3 2 35 3 3 8 3 4 21 3 5 27 3 6 12 (12 row(s) affected) 

您可以编写一个表值函数来执行拆分,然后将该结果与查找表连接起来。

您是否有兴趣更改架构? 通常,在单个字段中存储多个数据是一种可怕的做法。 一对多关系似乎更合适。

你可能想看看这个:

http://www.sommarskog.se/arrays-in-sql.html

并使用它来使用IN子句执行子查询。