我有这个SQL查询
SELECT t.id AS taskid,
STUFF(
(
SELECT ',' + x.tID
FROM (
SELECT CAST(id AS VARCHAR(200)) AS tid
FROM CRSTask c WHERE c.ParentTask =
7562 -- comment this line
) x
FOR XML PATH('')
),
1,
1,
''
) AS strIDS
FROM CRSTask t
WHERE t.ParentTask IS NULL
AND t.id = 7562 -- comment this line
此查询的结果将是:
id strIDS
7562 7615,7616,7617,7618,7619,7620,7621,7631,7632,123
这很好,但是当我尝试用另一个表中的名字替换strIDS
时,需要很多时间。
e.g。 123 [strIDS中的最后一个id]是来自CRSTask的taskID,与CRSTaskReceiver有一对一的关系 和taskReceiver有一对一的关系到Portal_Users_View(id,userName) - 我需要用等效的userName替换123 - 我使用了连接...它需要花费很多时间,也使用表之间的位置需要很多时间
答案 0 :(得分:0)
回答你的问题:在我看来,99%的案例中JOIN更好,因为它们更清楚地显示了基础数据模型。这样可以更轻松地维护代码,查询优化器也可以更轻松地提出合适的查询计划。
我不是UDF的忠实粉丝,但在这种情况下,它可能是解决问题的最简单方法,因为MSSQL本身不支持聚合字符串:
-- create User Defined Function to fetch list of names for given taskid
CREATE FUNCTION dbo.fn_names_from_taskid ( @taskid int )
RETURNS nvarchar(max)
AS
BEGIN
DECLARE @result nvarchar(max)
SELECT @result = ''
SELECT @result = @result
+ Portal_Users_View.ArabicName + ','
FROM Portal_Users_View
JOIN CRSTaskReceiver
ON CRSTaskReceiver.ReceiverID = Portal_Users_View.ID
JOIN CRSTask c
ON CAST(c.id AS VARCHAR(200)) = CRSTaskReceiver.CRSTaskID -- cast really necessary?
AND c.ParentTask = @taskid
-- strip last comma (if present)
SELECT @result = (CASE WHEN Right(@result, 1) = ',' THEN Left(@result, Len(@result) - 1) ELSE @result END)
Return(@result)
END
GO
-- usage
SELECT taskid = t.id,
nameslist = dbo.fn_names_from_taskid (t.id)
INTO #test
WHERE id = 7652
PS:我试图从上面的代码解释你的数据模型,你需要仔细检查它!
PS:Cast()真的有必要吗?我会假设所有id字段都存储为int?!?如果是这样(并且使用正确的索引)那些连接应该是“非常快”,但是使用Cast(),服务器无法正确使用其索引,并且您可能在性能方面具有最奇怪的行为。