我有一个查询,结果如下: 查询:
SELECT Tasks.TaskId, Comments.Comment, comments.timespent
FROM comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
WHERE ( comments.entity = 1 )
GROUP BY Tasks.TaskId, Comments.Comment, comments.timespent
结果:
TaskID Comment TimeSpent
__________________________
111754 C1 4
111754 C2 1
111754 C3 79
请告诉我如何编写查询以获得如下结果:
TaskID Comment TimeSpent
__________________________________
111754 ,C1,C2,C3 84
提前致谢。
答案 0 :(得分:12)
这是工作的SQL小提琴:http://sqlfiddle.com/#!3/3597a/3
这是实际工作的SQL。
SELECT Tasks.TaskId, SUBSTRING(
(SELECT ',' + Comments.Comment
FROM Comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
FOR XML PATH('')),2,200000) AS Comments
, SUM(comments.timespent) AS TimeSpent
FROM comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
WHERE ( comments.entity = 1 )
GROUP BY Tasks.TaskId
CREATE TABLE Tasks
(
TaskID NVARCHAR(20) NOT NULL,
);
CREATE TABLE Comments
(
Entity INT NOT NULL,
EntityID NVARCHAR(20) NOT NULL,
Comment NVARCHAR(50) NOT NULL,
TimeSpent INT NOT NULL
);
INSERT INTO Tasks VALUES
( '111754' );
INSERT INTO Comments VALUES
(1,'111754', 'C1',4 ),
(1,'111754', 'C2',1 ),
(1,'111754', 'C3',79 );
SELECT Tasks.TaskId, SUBSTRING(
(SELECT ',' + Comments.Comment
FROM Comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
FOR XML PATH('')),2,200000) AS Comments
, SUM(comments.timespent) AS TimeSpent
FROM comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
WHERE comments.entity = 1
GROUP BY Tasks.TaskId
TASKID COMMENTS TIMESPENT
111754 C1,C2,C3 84
答案 1 :(得分:2)
您应该查看FOR XML PATH
。
答案 2 :(得分:2)
您可以使用XML路径进行CROSS APPLY,例如:
`
Select *
from table1 t1
CROSS APPLY
(
SELECT
[text()] = t.[Name] + '; '
FROM table2 t2
WHERE t1.[Id] = t2.[Id]
ORDER BY t2.name
FOR XML PATH('')
) a (Type)
`
答案 3 :(得分:1)
好的,这有点复杂,但它没有使用xml,它可以用于除sql server之外的其他数据库:
WITH orig
AS (SELECT 1 AS f1, 'C11' AS f2
UNION ALL
SELECT 1 AS f1, 'C12' AS f2
UNION ALL
SELECT 1 AS f1, 'C13' AS f2
UNION ALL
SELECT 2 AS f1, 'C21' AS f2
UNION ALL
SELECT 2 AS f1, 'C22' AS f2
UNION ALL
SELECT 2 AS f1, 'C23' AS f2
UNION ALL
SELECT 3 AS f1, 'C31' AS f2)
, orig2 AS (SELECT DISTINCT f1, f2 FROM orig)
, orig3 AS (SELECT f1, f2, row_number() OVER(PARTITION BY f1 ORDER BY f2) AS RowNum FROM orig2)
, orig4
-- Use recursion to concatenate the fields
AS (SELECT f1, CONVERT(VARCHAR(MAX), f2) AS val, rownum
FROM orig3
WHERE RowNum = 1
UNION ALL
SELECT orig4.f1, orig4.val + ', ' + orig3.f2 AS val, orig3.rownum
FROM orig4
INNER JOIN orig3
ON orig4.RowNum + 1 = orig3.RowNum
AND orig4.f1 = orig3.f1)
SELECT *
FROM orig4
-- select only the rows that match the maximum rownum
WHERE NOT EXISTS
(SELECT 1
FROM orig4 o44
WHERE o44.f1 = orig4.f1
AND o44.rownum > orig4.rownum)
另一种仅适用于sql server的方法是构建一个连接值的聚合CLR函数:http://msdn.microsoft.com/en-us/library/91e6taax%28v=vs.90%29.aspx。
如果你遇到过这篇文章但是你使用了oracle,你可以选择使用上面的查询或者在pl / sql(http://docs.oracle.com/cd/B28359_01/appdev.111/b28425/aggr_functions.htm)中定义自定义聚合函数。
答案 4 :(得分:0)
您应该使用 STRING_AGG
函数。它是一个用于字符串的 sql 聚合器函数。我认为您的最终查询将是:
SELECT Tasks.TaskId, STRING_AGG(Comments.Comment, ', '), SUM(comments.timespent)
FROM comments
INNER JOIN tasks ON comments.entityid = tasks.taskid
WHERE ( comments.entity = 1 )
GROUP BY Tasks.TaskId