2016-06-23 26 views
5

mam poniżej Stored Procedure -Jak obsługiwać pustych wierszy w CROSS APPLY [SQL Server]

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 

Teraz, kiedy execute powyższy SP z poniżej PostID -

--[Mercola_Optimized_GetArticlePostAMP] 732490 otrzymuję poniżej dane, które są expected. Jako, zapytanie wewnątrz cross apply ma dane dla powyższego postID.

enter image description here

Ale teraz, kiedy execute ten sam SP z poniżej inny PostID -

--[Mercola_Optimized_GetArticlePostAMP] 40702 otrzymuję poniżej empty data [rows]. Jako, zapytanie wewnątrz cross apply nie ma danych dla powyższego postID Infact, inne joins mają dane.

enter image description here

Oczekiwany wynik dla powyższego przypadku - zwróci dane i przypisując wartość domyślna dla CROSS APPLY. Jak mogę to zrobić?

+3

Użyj 'OUTER APPLY' zamiast – gofr1

+2

@ gofr1 Dzięki, zadziałało. Ale teraz chcę przypisać wartość domyślną, gdy nie ma danych .. –

+0

Formalizuję wszystko w jednej odpowiedzi. Patrz poniżej. – gofr1

Odpowiedz

8

Zastosowanie OUTER APPLY zamiast CROSS APPLY

Do przekroczenia wartości null używać ISNULL(MH.LastModifiedDate, @DefaultValue) as LastModifiedDate

2

zmienić zapytanie do Outer Zastosuj który zachowa wiersze z lewej strony, nawet jeśli nie znaleziono żadnego meczu

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

Krzyż zastosowanie jest podobne do Inner Join, więc będzie można dostać tylko pasujące wiersze, Outer apply jest jak Left join który zachowa lewą tabelę, nawet jeśli nie ma żadnych pasujących wierszy

zmiana:

jeśli chcesz ass IGN wartość domyślna dla zewnętrznego zastosowania rzędzie w przypadku null, wystarczy użyć IsNull w wybranej

coś jak poniżej:

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

Dzięki temu zadziałał jak urok. Ale chcę przypisać wartość domyślną, zwracając 'NULL' –