I want to improve the code of the following stored procedure. I want to join it into single select statement. Can you purpose a better way?
CREATE PROCEDURE [dbo].[pr_FinDocument_Filter]
@finDocIdForFilter [dbo].[GuidList] READONLY,
@filteredSid nvarchar(64),
@filteringOffsetInDay int
AS
BEGIN
IF (@filteredSid is null or @filteringOffsetInDay is null)
BEGIN
RAISERROR(N'arguments must have a value', 15, 1);
END
IF EXISTS (SELECT 1 FROM @finDocIdForFilter)
BEGIN
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
INNER JOIN @finDocIdForFilter AS fin_doc_for_filter
ON fin_doc_extra.docId = fin_doc_for_filter.Id
AND fin_doc_extra.sid = @filteredSid
WHERE
DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
END
ELSE
BEGIN
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE
fin_doc_extra.sid = @filteredSid
AND DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
END
END
I think that merging 2 selects into one will not necessary improve your code. For comparison, here is an example how you can do that. We have 1 query but it is more complex and can be perceived as less readable.
The query below is based on your your second query. I modified it by adding an additional condition to WHERE statement. This extra condition will be satisfied if @finDocIdForFilter
is empty or if @finDocIdForFilter
contains matching rows.
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE
fin_doc_extra.sid = @filteredSid AND
DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND
(
NOT EXISTS(SELECT 1 FROM @finDocIdForFilter)
OR
EXISTS(
SELECT 1
FROM @finDocIdForFilter AS fin_doc_for_filter
ON fin_doc_extra.docId = fin_doc_for_filter.Ida.AssetCode)
)
I think this might work for you.
SELECT fin_doc_extra.docID
FROM [CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105),
CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND fin_doc_extra.sid = @filteredSid
AND ( ( fin_doc_extra.docId IN ( SELECT fin_doc_for_filter.Id
FROM @finDocIdForFilter ) )
OR ( NOT EXISTS ( SELECT 1
FROM @finDocIdForFilter )
)
);
I have an idea about left outer join
SELECT TABLEA.Id
FROM
TABLEA
left join TVP
on TVP.Id = TABLEA.Id
WHERE
TABLEA.sid = @filteredSid
AND DATEDIFF(DAY, CONVERT(DATE, TABLEA.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND
(
TVP.Id is not null
OR
NOT EXISTS (SELECT 1 FROM TVP)
)
来源:https://stackoverflow.com/questions/33500134/how-to-improve-the-code-of-stored-procedure-with-inner-join-to-possible-empty-tv