SELECT ISNULL((
SELECT new_faultphenomenonname + '<br />'
FROM new_srv_faultdetailBase fb WITH (NOLOCK)
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
),'') new_faultphenomenonname --故障现象
,ISNULL((
SELECT new_faultreasonname + '<br />'
FROM new_srv_faultdetailBase fb WITH (NOLOCK)
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
),'') new_faultreasonname --故障原因
,ISNULL((
SELECT isreappear.name + '<br />'
FROM new_srv_faultdetailBase fb WITH (NOLOCK)
OUTER APPLY fn_GetPickListName('new_srv_faultdetail',
'new_isreappear',
fb.new_isreappear) isreappear
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
),'') new_isreappear --是否重现
FROM new_srv_detectionorderBase wb WITH (NOLOCK);
new_srv_faultdetailBase 加入强索引,提升查询效率...
你碰到啥問題,為啥要優化?
效能?不好維護?
这样的子查询列存在多个且同一个表,是否能把这个子查询提取出来,一次查询组装好再放到列上?
@拾梦小侠ด้้้:
三個欄位要分別組成三個字串,就只能這樣寫了
@RosonJ: 这就尴尬了
三个子查询条件一样,fb和wb 可以一次连表查出来
字符的组合正常应该放到 上层应用上。非要在sql里拼,那就在前一查询基础上再套一层。
没有xml的大概应该可以这样 (没弄过xml 的,自行调试)
select case new_faultphenomenonname when is null then '' else new_faultphenomenonname +"<br/>" end .... from ( select * from fb left join wb on wb.new_srv_detectionorderid = fb.new_srv_detectionorderid)
不行哦,这个主表和明细表存在一对多关系,不是简单的只是串接了"<br/>" ,而是明细表多条记录串接
SELECT ISNULL(( SELECT new_faultphenomenonname + '<br />'
FROM new_srv_faultdetailBase fb WITH ( NOLOCK )
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
), '') new_faultphenomenonname --故障现象
,
ISNULL(( SELECT new_faultreasonname + '<br />'
FROM new_srv_faultdetailBase fb WITH ( NOLOCK )
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
), '') new_faultreasonname --故障原因
,
ISNULL(( SELECT isreappear.name + '<br />'
FROM new_srv_faultdetailBase fb WITH ( NOLOCK )
OUTER APPLY fn_GetPickListName('new_srv_faultdetail',
'new_isreappear',
fb.new_isreappear) isreappear
WHERE wb.new_srv_detectionorderid = fb.new_srv_detectionorderid
FOR
XML PATH('')
), '') new_isreappear --是否重现
FROM new_srv_detectionorderBase wb WITH ( NOLOCK ) GROUP BY new_srv_detectionorderid;
最后应该group by 一下不然会查询结果会出现多条重复数据。
大兄弟,不存在的,这group by多余了...
还有其他条件的,别担心...
@拾梦小侠ด้้้:
有重复数据可以加个distinct
@拾梦小侠ด้้้: 你这个用子查询了,肯定有多条new_srv_detectionorderid相同的数据,只有一条数据不需要子查询了。
@拾梦小侠ด้้้: 还有其他条件建议先把需要的数据过滤出来放到临时表,再进行数据子查询。
@杨jian: 你可能对FOR XML PATH('') 有误会
@杨jian: new_srv_detectionorderBase 、new_srv_faultdetailBase 都是几百万的数据,最低条件结果集也是几十万的数据,觉得用临时表合适?
@拾梦小侠ด้้้: ```sql
SELECT new_srv_detectionorderid
INTO #temp_new_srv_faultdetailBase
FROM new_srv_faultdetailBase fb WITH ( NOLOCK )
GROUP BY new_srv_detectionorderid
CREATE TABLE #temp_result
(
new_srv_detectionorderid INT ,
new_faultphenomenonname NVARCHAR(MAX) ,
new_faultreasonname NVARCHAR(MAX) ,
new_isreappear NVARCHAR(MAX)
)
DECLARE @new_srv_detectionorderid INT ,
@new_faultphenomenonname NVARCHAR(MAX)= '' ,
@new_faultreasonname NVARCHAR(MAX)= '' ,
@new_isreappear NVARCHAR(MAX)= ''
WHILE ( EXISTS ( SELECT 1
FROM #temp_new_srv_faultdetailBase ) )
BEGIN
SELECT TOP 1
@new_srv_detectionorderid = new_srv_detectionorderid
FROM #temp_new_srv_faultdetailBase
SELECT @new_faultphenomenonname+= new_faultphenomenonname + '</br>' ,
@new_faultreasonname+= new_faultreasonname + '</br>' ,
@new_isreappear+= isreappear.name + '</br>'
FROM new_srv_faultdetailBase fb
OUTER APPLY fn_GetPickListName('new_srv_faultdetail',
'new_isreappear',
fb.new_isreappear)
WHERE new_srv_detectionorderid = @new_srv_detectionorderid
INSERT INTO #temp_result
( new_srv_detectionorderid ,
new_faultphenomenonname ,
new_faultreasonname ,
new_isreappear
)
VALUES ( @new_srv_detectionorderid ,
@new_faultphenomenonname ,
@new_faultreasonname ,
@new_isreappear
)
DELETE #temp_new_srv_faultdetailBase
WHERE new_srv_detectionorderid = @new_srv_detectionorderid
END
SELECT wb.new_srv_detectionorderid ,
tr.new_faultphenomenonname ,
new_faultreasonname ,
new_isreappear
FROM new_srv_detectionorderBase wb WITH ( NOLOCK )
LEFT JOIN #temp_result tr ON wb.new_srv_detectionorderid = tr.new_srv_detectionorderid
DROP TABLE #temp_new_srv_faultdetailBase
DROP TABLE #temp_result
先把子查询的结果查询出来,再主表left join,这样减少子查询次数。
@杨jian: 非常感谢你的积极!不过在你没搞明白这个查询的原意,你的积极有点儿多余,请自行 了解下FOR XML PATH('') ,顺便当一波学习,谢谢!
@拾梦小侠ด้้้: 这个不就是一个主表,子查询子表符合条件的数据拼接起来?我这个先把拼接结果处理好,减少子查询扫表次数,我觉得是达到了优化效果。FOR XML PATH('') 不就是数据拼接?
@杨jian: 嗯,不好意思,我个人看错了,你的方式是可行的,只是这边当前无法用临时表处理这个问题,谢谢!
可以写存储过程将内容再以表的方式返回查询,这样效率岂不更好!
建议改进一下排版,支持 markdown 代码高亮语法
– dudu 3年前