我不确定这在SQL中是否可行,如果不是,我会以编程方式进行 - 但如果有办法,它会很棒。
基本上,我在一个表中有一个列,它用另一个表中的ID填充,用逗号分隔 - 所以字段可能如下所示:
3,4,9
这些链接到另一个表,其中上面字段中的数字是行的主键。在行中是一个描述,我想向用户显示而不是数字。
基本上,我不想向用户显示3,4,9,而是想在另一个表中查找相关描述。这可能吗?
答案 0 :(得分:2)
您可以编写一个表值函数来执行拆分,然后将该结果与查找表结合起来。
答案 1 :(得分:1)
克里斯,
有一种方法可以在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 t.N),
ItemValue = SUBSTRING(@pString,t.N+1,ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,t.N+1),0),DATALENGTH(@pString)+1)-t.N-1)
FROM cteTally t
WHERE t.N BETWEEN 0 AND DATALENGTH(@pString)
AND (SUBSTRING(@pString,t.N,1) = @pDelimiter OR t.N = 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)
答案 2 :(得分:0)
答案 3 :(得分:0)
您是否有兴趣更改架构?通常,在单个字段中存储多个数据是一种可怕的做法。一对多关系似乎更合适。