我有一个看起来像这样的查询
SELECT J.JobID,T.Title FROM JobsTagMap J
Left Join Tags T
ON J.TagID=T.TagID
返回以下数据集(简化,JobID实际上是UniqueIdentifier)
JobID Title
1 Tag1
1 Tag2
2 Tag2
2 Tag5
2 Tag9
现在,我想通过JobID列对其进行分组并连接Title,所以结果如下
JobID Title
1 Tag1,Tag2
2 Tag2,Tag5,Tag9
我该怎么做?
答案 0 :(得分:10)
如果您使用的是sql server 2005+。然后你可以这样做:
SELECT
JobsTagMap.JobID,
STUFF
(
(
SELECT
',' +Title
FROM
Tags
WHERE
Tags.TagID=JobsTagMap.TagID
FOR XML PATH('')
)
,1,1,'') AS Title
FROM JobsTagMap
修改强>
因为您没有向我们展示表结构和不同表中的数据。这有点难以理解。所以我假设你的表结构看起来像这样:
CREATE TABLE JobsTagMap
(
JobID INT,
TagID INT
)
CREATE TABLE Tags
(
TagID INT,
Title VARCHAR(100)
)
有了这些数据:
INSERT INTO JobsTagMap
VALUES(1,1),(1,2),(2,2),(2,4),(2,5)
INSERT INTO Tags
VALUES(1,'Tag1'),(2,'Tag2'),(3,'Tag2'),(4,'Tag5'),(5,'Tag9')
如果您获得的是您所显示的数据JobID
不能是唯一的。您可能在某个地方有一个Job
表,它是唯一的。如果您只想使用这些表格,那么您需要执行以下操作:
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY JobID ORDER BY JobID) AS RowNbr,
JobsTagMap.*
FROM
JobsTagMap
)
SELECT
*,
STUFF
(
(
SELECT
',' +Title
FROM
Tags
JOIN JobsTagMap
ON Tags.TagID=JobsTagMap.TagID
WHERE
JobsTagMap.JobID=CTE.JobID
FOR XML PATH('')
)
,1,1,'') AS Title
FROM
CTE
WHERE
CTE.RowNbr=1
这会得到这个结果:
1 1 1 Tag1,Tag2
1 2 2 Tag2,Tag5,Tag9
因此,将来始终会显示表格结构以及数据。那会给你更好的答案
答案 1 :(得分:1)
我正是使用标量函数。有一些纯粹主义者认为解密应该永远不会使用基于行的操作,但是嘿这是有效的,如果你只返回几行,那么响应时间就可以了。
CREATE FUNCTION [dbo].[JoinMVText]
(
@sID int,
@fieldID tinyint
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @MVtextList varchar(max)
SELECT @MVtextList = COALESCE(@MVtextList + '; ', '') + docMVtext.value
FROM docMVtext with (nolock)
WHERE docMVtext.sID = @sID and fieldID = @fieldID
RETURN @MVtextList
END
答案 2 :(得分:0)
我遇到了与您同样的问题,并且找出了解决慢速子选择的方法。
使用 GROUP BY :
(70500 rows affected)
SQL Server Execution Times:
CPU time = 94 ms, elapsed time = 833 ms.
使用子选择:
(70500 rows affected)
SQL Server Execution Times:
CPU time = 1469 ms, elapsed time = 2323 ms.
子选择要慢4倍以上...
这是解决方案:
SELECT
J.JobID,
STRING_AGG(ISNULL(T.Title, ''), ',') as Title
FROM JobsTagMap J
LEFT JOIN Tags T ON J.TagID = T.TagID
GROUP BY J.JobID;
让我知道是否有些不清楚:)