连接按列分组的值
Concatenate values that are grouped by a column
我有以下 table:
Code Ref Value
A1 Car A
A1 Car -
A1 Car B
B2 Truck CC
B2 Truck D
B2 Truck -
C3 Van E
C3 Van F
C3 Van -
C3 Van G
我要实现的目标是将所有值组合在一起的串联字符串,如下所示:
Code Ref Value
A1 Car A-B
B2 Truck CCD-
C3 Van EF-G
我偏离了示例 here,但一无所获。这是我想出的:
SELECT [Table].[Code]
, [Table].[Ref]
, STUFF((SELECT DISTINCT [Value]
FROM [Table2]
FOR XML PATH ('')),1, 1,'') AS Values
FROM [Table]
LEFT JOIN [Table2] ON
[Table2].[Code] = [Table].[Code]
我哪里错了?有没有更有效的方法来做到这一点?
您没有任何 link 对 [Table]
的内部和外部引用,并且您还需要使外部引用不同。最后,您需要在子查询中没有列名,或者需要 [text()]
SELECT [Code]
,[Ref]
,STUFF((SELECT DISTINCT [Value] AS [text()]
FROM [Table] AS T2
WHERE T1.Code = T2.Code -- LINK HERE
AND T2.Ref = T2.Ref -- AND HERE
FOR XML PATH ('')
),1, 1,'') AS [Values]
FROM [Table] AS T1
GROUP BY T1.Code, T1.Ref; -- GROUP BY HERE
顺便说一句,您不需要使用 STUFF
,因为您没有定界符,STUFF
通常用于从字符串的开头删除所选的定界符。因此,当您有一个像 ,value1,value2,value3
这样的字符串时,STUFF(string, 1, 1, '')
会将第一个字符替换为 ''
,从而使您得到 value1,value2,value3
.
你还应该使用 value
xquery 方法来确保你不会被特殊字符绊倒,如果你不这样做,你可以尝试连接 ">>"
和 "<<"
你不会像您想要的那样以 ">><<"
结尾,您会得到 ">><<"
,因此更好的查询是:
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = [Value]
FROM [Table] AS t2
WHERE T1.Code = T2.Code
AND T2.Ref = T2.Ref
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM [Table] AS T1
GROUP BY t1.Code, t1.Ref;
附录
根据对问题的最新编辑,您的 Value
列似乎来自另一个 table,link 编辑到第一个 table Code
。如果有的话,这会使您的查询更简单。您不需要 JOIN
,但您仍然需要确保有一个表达式 link 从外部 table 到内部 table 您的子查询。我假设行在第一个 table 中是唯一的,因此您可能不需要分组依据:
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = t2.[Value]
FROM [Table2] AS t2
WHERE T1.Code = T2.Code
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM [Table] AS T1;
工作示例
CREATE TABLE #Table1 (Code CHAR(2), Ref VARCHAR(10));
INSERT #Table1 VALUES ('A1', 'Car'), ('B2', 'Truck'), ('C3', 'Van');
CREATE TABLE #Table2 (Code CHAR(2), Value VARCHAR(2));
INSERT #Table2
VALUES ('A1', 'A'), ('A1', '-'), ('A1', 'B'),
('B2', 'CC'), ('B2', 'D'), ('B2', '-'),
('C3', 'F'), ('C3', '-'), ('C3', 'G');
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = t2.[Value]
FROM #Table2 AS t2
WHERE T1.Code = T2.Code
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM #Table1 AS T1;
我有以下 table:
Code Ref Value
A1 Car A
A1 Car -
A1 Car B
B2 Truck CC
B2 Truck D
B2 Truck -
C3 Van E
C3 Van F
C3 Van -
C3 Van G
我要实现的目标是将所有值组合在一起的串联字符串,如下所示:
Code Ref Value
A1 Car A-B
B2 Truck CCD-
C3 Van EF-G
我偏离了示例 here,但一无所获。这是我想出的:
SELECT [Table].[Code]
, [Table].[Ref]
, STUFF((SELECT DISTINCT [Value]
FROM [Table2]
FOR XML PATH ('')),1, 1,'') AS Values
FROM [Table]
LEFT JOIN [Table2] ON
[Table2].[Code] = [Table].[Code]
我哪里错了?有没有更有效的方法来做到这一点?
您没有任何 link 对 [Table]
的内部和外部引用,并且您还需要使外部引用不同。最后,您需要在子查询中没有列名,或者需要 [text()]
SELECT [Code]
,[Ref]
,STUFF((SELECT DISTINCT [Value] AS [text()]
FROM [Table] AS T2
WHERE T1.Code = T2.Code -- LINK HERE
AND T2.Ref = T2.Ref -- AND HERE
FOR XML PATH ('')
),1, 1,'') AS [Values]
FROM [Table] AS T1
GROUP BY T1.Code, T1.Ref; -- GROUP BY HERE
顺便说一句,您不需要使用 STUFF
,因为您没有定界符,STUFF
通常用于从字符串的开头删除所选的定界符。因此,当您有一个像 ,value1,value2,value3
这样的字符串时,STUFF(string, 1, 1, '')
会将第一个字符替换为 ''
,从而使您得到 value1,value2,value3
.
你还应该使用 value
xquery 方法来确保你不会被特殊字符绊倒,如果你不这样做,你可以尝试连接 ">>"
和 "<<"
你不会像您想要的那样以 ">><<"
结尾,您会得到 ">><<"
,因此更好的查询是:
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = [Value]
FROM [Table] AS t2
WHERE T1.Code = T2.Code
AND T2.Ref = T2.Ref
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM [Table] AS T1
GROUP BY t1.Code, t1.Ref;
附录
根据对问题的最新编辑,您的 Value
列似乎来自另一个 table,link 编辑到第一个 table Code
。如果有的话,这会使您的查询更简单。您不需要 JOIN
,但您仍然需要确保有一个表达式 link 从外部 table 到内部 table 您的子查询。我假设行在第一个 table 中是唯一的,因此您可能不需要分组依据:
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = t2.[Value]
FROM [Table2] AS t2
WHERE T1.Code = T2.Code
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM [Table] AS T1;
工作示例
CREATE TABLE #Table1 (Code CHAR(2), Ref VARCHAR(10));
INSERT #Table1 VALUES ('A1', 'Car'), ('B2', 'Truck'), ('C3', 'Van');
CREATE TABLE #Table2 (Code CHAR(2), Value VARCHAR(2));
INSERT #Table2
VALUES ('A1', 'A'), ('A1', '-'), ('A1', 'B'),
('B2', 'CC'), ('B2', 'D'), ('B2', '-'),
('C3', 'F'), ('C3', '-'), ('C3', 'G');
SELECT t1.Code,
t1.Ref,
[Values] = (SELECT DISTINCT [text()] = t2.[Value]
FROM #Table2 AS t2
WHERE T1.Code = T2.Code
FOR XML PATH (''), TYPE
).value('.', 'NVARCHAR(MAX)')
FROM #Table1 AS T1;