如何处理 CROSS APPLY [SQL Server] 中的空行

Posted

技术标签:

【中文标题】如何处理 CROSS APPLY [SQL Server] 中的空行【英文标题】:How to handle empty rows in CROSS APPLY [SQL Server] 【发布时间】:2016-06-23 09:53:39 【问题描述】:

我在下面Stored Procedure-

ALTER PROCEDURE [dbo].[Optimized_GetArticlePostAMP]                                                              
(                                                                                    
 @PostID int                                                                                    
)                                                                                          

AS                                                                                    
BEGIN                                                                                    
SET NOCOUNT ON;                                                                                    
SET STATISTICS TIME ON                                                    

DECLARE @SectionId int ,@datediff int                                            
DECLARE @postdate datetime

 SELECT P.PostId, P.SectionID, P.PostName,MP.MetaTitle,P.Postdate,P.PostAuthor,P.IsApproved,                                                                                             
 MP.Metadescription, MP.Metakeywords,ISNULL(MP.IsRobotsMetaTag,0) as IsRobotsMetaTag,p.TotalViews, P.Subject, P.FormattedBody,                                                                                               
 MV.Isvideo,MV.VideoCode,MV.VideoCaption, A.DrComment,A.SpanishURL, PS.RedirectUrl, Isnull(PS.IsRedirect,0) as IsRedirect,                                     
 ISNULL(A.CommentedBy,38633) as CommentedBy ,MP.Canonical as Canonical,ISNULL(MP.RRpopUP ,0) as RRpopUP,ISNULL(A.PrevPost,0) as PreviousPostId,        
 ISNULL(A.NextPost,0) as NextPostId,PS.StatusId ,dbo.[mercola_GetCommentCountForPost](@PostId) as TotalReplies, isnull(PA.[FileName],'') as FileName,         
 PRD.StoryImage, PRD.StoryContent, ISNULL(NULLIF(prd.ALT, ''), P.Subject) AS ALT, ISNULL(PR.ReferenceData,'')as ReferenceData,       
 MH.LastModifiedDate,    
 CASE WHEN CHARINDEX('<p><strong>By', FormattedBody, -1)=1 THEN LTRIM(SUBSTRING(REPLACE(CAST(FormattedBody as varchar(max)),'<p><strong>By ',''),0,CHARINDEX('<',REPLACE(cast(FormattedBody as varchar(max)),'<p><strong>By ',''))))   
 ELSE 'Dr.Mercola' END as Name  
 FROM cs_posts P        
 LEFT JOIN Mercola_NewsletterDetails A on (P.Postid = A.postid)                                                                                       
 LEFT JOIN Mercola_PostStatus PS on (PS.postid=p.postid)                                                    
 LEFT JOIN Mercola_PostMetatags MP on(P.postid=MP.Postid)                                                                                             
 LEFT JOIN Mercola_postVideo MV  on(P.postid=MV.Postid)                                                      
 LEFT JOIN CS_PostAttachments PA on P.PostId=PA.PostId AND PA.contenttype LIKE 'audio/mpeg' AND PA.FILENAME LIKE '%.mp3' AND PA.isremote = 1                                                    
 LEFT JOIN Mercola_PostRelatedData PRD on P.PostId=PRD.PostId                                                  
 LEFT JOIN Mercola_PostReferences PR on P.PostId=PR.PostId        
 CROSS APPLY (select top 1 LastModifiedDate from Mercola_ArticleModifiedHistory where Mercola_ArticleModifiedHistory.Postid = P.postid order by LastModifiedDate desc)MH                                                  
 where P.Postid = @Postid 

现在,当我execute 上面的SP 和下面的PostID -

--[Mercola_Optimized_GetArticlePostAMP] 732490 我得到以下数据,即expected。因为cross apply里面的查询有上面postID的数据。

但是现在,当我execute 相同的SP 与下面不同的PostID -

--[Mercola_Optimized_GetArticlePostAMP] 40702 我低于empty data [rows]。因为cross apply里面的查询没有上面postID的数据其实其他joins有数据。

上述案例的预期结果 - 返回数据并为CROSS APPLY 分配默认值。我该怎么做?

【问题讨论】:

改用OUTER APPLY @gofr1 谢谢,它成功了。但是现在我想在没有数据时分配默认值.. 我在一个答案中正式化了所有内容。请看下文。 【参考方案1】:

使用OUTER APPLY 代替CROSS APPLY

要溢出 NULL,请使用 ISNULL(MH.LastModifiedDate, @DefaultValue) as LastModifiedDate

【讨论】:

【参考方案2】:

将您的查询更改为外部应用,即使没有匹配项也会保留左侧的行

   outer APPLY (select top 1 LastModifiedDate
    from ArticleModifiedHistory 
    where ArticleModifiedHistory.Postid = P.postid order by LastModifiedDate desc

交叉应用类似于Inner Join,所以你只会得到匹配的行,Outer apply就像Left join,即使没有匹配的行也会保留你的左表

更新:

如果你想在 null 的情况下为外部应用行分配默认值,只需在 select 中使用 IsNull

如下所示:

select *,isnull(b.id,'defaultvalue') from test1 t1 
outer apply(select id from test2 t2 where t1.id=t2.id) b

【讨论】:

感谢它的魅力。但我想分配默认值,因为它返回 NULL

以上是关于如何处理 CROSS APPLY [SQL Server] 中的空行的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Gmail 地址?

Wordpress SQL 默认搜索,如何处理 SQL 注入

跨域在Spring Boot中如何处理

如何处理耗时的 SQL?

如何处理 SQL 代理作业错误?

Oracle 如何处理给定的 SQL 语句