我有一个非常复杂的存储过程,但我的SQL不那么强,请任何具有强大SQL专业知识并可以帮助我进行优化或至少可以给我一个提示的人,该过程将从数据库中选择收件箱消息针对特定用户,它包含许多其他参数,例如分页和类别以及语言输入和许多其他详细信息:
ALTER PROCEDURE [dbo].[Inbox]
@ConfidentialityIds NVARCHAR(100) = '0,1,2,3',
@UrgencyIds NVARCHAR(100) = '0,1,2,3',
@CorrespondenceCategoryIds NVARCHAR(100) = '1,2,3,5,6,7',
@CorrespondenceExtendedCategoryIds NVARCHAR(MAX),
@IsPrivate bit = 0,
@IsSaved bit = 0,
@Importantance VARCHAR(10) = '0, 1',
@UserId uniqueidentifier,
@SelectedPage int = 1,
@PageSize int = 25,
@Now bigint,
@IsImpersonated bit,
@ActualLoggedInUserId uniqueidentifier,
@IsEnglish bit,
@OnlyArchived bit = null,
@replaceNameWithEntName bit,
@entityIds nvarchar(MAX),
@OnlyLate bit = 0,
@Statuses NVARCHAR(100) ='1,2,3,4,5',
@ApplyPageFilter bit = 1,
@IsBundled int,
@showArchivedInCCInbox bit = 0,
@appModuleId INT = 0
WITH RECOMPILE
As
BEGIN
SET transaction isolation level read uncommitted
DECLARE @lFirstRec INT, @lLastRec INT, @lTotalRows INT
SET @lFirstRec = ( @SelectedPage - 1 ) * @PageSize
SET @lLastRec = ( @SelectedPage * @PageSize + 1 )
SET @lTotalRows = @lFirstRec - @lLastRec + 1
DECLARE @isPersonalDelegationAvailable BIT = 0
IF EXISTS(
SELECT 1
FROM DelegatedToEntityUsers d
WHERE d.DelegatedToUserId = @ActualLoggedInUserId
AND d.DelegatedFromUserId = @UserId
AND
(
d.DelegatedToEntityId IS NULL OR d.DelegationType = 1
))
BEGIN
SET @isPersonalDelegationAvailable = 1
END
DECLARE @tblEntities TABLE(Value INT)
INSERT INTO @tblEntities
SELECT Value FROM SplitCommaUniqueValues(@entityIds)
Select * from (
Select (ROW_NUMBER() OVER (ORDER BY K.ActionDate DESC, K.CorrespondenceDate DESC)) AS RowIndex,
Count(*) over () AS TotalCount,*
from (
select (ROW_NUMBER() OVER (PARTITION BY CorrespondenceID Order by CorrespondenceID DESC)) AS CorrId, *
from (
SELECT Distinct * FROM
(
SELECT
CONVERT(VARCHAR(100), R.CorrespondenceActionRecipientID) Id,
A.CorrespondenceActionID ActionId,
(CASE WHEN R.RecipientType IS NULL THEN NULL ELSE CAST(RecipientType AS INT) END) RecipientType,
A.ActionTypeId,
(CASE when @IsEnglish = 1 then ATypes.FriendlyTextEN else ATypes.FriendlyTextAR end) ActionTypeName,
A.ActionCreatedByUserID SentById,
CASE
when @replaceNameWithEntName = 0 then ISNULL(ActionCreatedByUser.ShortName, ActionCreatedByUser.EmployeeName)
when @replaceNameWithEntName = 1 and SentByEntity.EntityID not in (SELECT Value FROM @tblEntities) then case when @IsEnglish = 1 then SentByEntity.EntityNameEn else SentByEntity.EntityNameAR end
when @replaceNameWithEntName = 1 and SentByEntity.EntityID in (SELECT Value FROM @tblEntities) then ISNULL(ActionCreatedByUser.ShortName, ActionCreatedByUser.EmployeeName)
END SentByFrom,
A.WithDelegateFromUserID OnBehalfOfId,
ISNULL(WithDelegateFromUser.ShortName, WithDelegateFromUser.EmployeeName) OnBehalfOfName,
R.UserId SentToId,
CASE
when @replaceNameWithEntName = 0 then ISNULL(SentToUser.ShortName, SentToUser.EmployeeName)
when @replaceNameWithEntName = 1 and SentToEntity.EntityID not in (SELECT Value FROM @tblEntities) then case when @IsEnglish = 1 then SentToEntity.EntityNameEn else SentToEntity.EntityNameAR end
when @replaceNameWithEntName = 1 and SentToEntity.EntityID in (SELECT Value FROM @tblEntities) then isnull(ISNULL(SentToUser.ShortName, SentToUser.EmployeeName), case when @IsEnglish = 1 then SentToEntity.EntityNameEn else SentToEntity.EntityNameAR end)
END SentToName,
R.EntityID SentToEntityId,
SentToEntity.EntityNameAR SentToEntityNameAR,
SentToEntity.EntityNameEN SentToEntityNameEN,
R.Seen,
(CASE WHEN MR.CorrespondenceActionRecipientID IS NOT NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) IsReadByUser,
CAST(ISNULL(FollowedByUser.IsFollowedByUser, 0) AS BIT) IsFollowedByUser,
(
CASE WHEN EXISTS(SELECT 1 FROM CorrespondenceFollowups
WHERE CorrespondenceID = C.CorrespondenceID
AND UserId = @UserId AND AssignedByUserId IS NOT NULL) THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
) IsAssignedFollowToUser,
(
CASE WHEN EXISTS(SELECT 1 FROM CorrespondenceFollowups
WHERE CorrespondenceID = C.CorrespondenceID
AND AssignedByUserId = @UserId) THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END
) IsAssignedFollowByUser,
A.CorrespondenceID,
A.ActionDate,
A.ActionDeadlineDate,
C.CompletionDate,
C.CorrespondenceDeadlineDate CorrDeadlineDate,
C.OwnerUserID CorrOwnerId,
C.ChildNo ChildNo,
OwnerUser.EmployeeName CorrOwnerName,
C.Important,
C.UrgencyId,
C.LetterCorrespondenceId,
(CASE when @IsEnglish = 1 then U.TextEN else U.TextAR end) UrgencyText,
C.ConfidentialityId,
(CASE when @IsEnglish = 1 then Confid.TextEN else Confid.TextAR end) ConfidentialityText,
C.CorrespondenceCategoryId CategoryId,
C.CorrespondenceClassificationID CorrespondenceClassificationID,
(CASE when @IsEnglish = 1 then CCat.TextEN else CCat.TextAR end) CategoryName,
CCat.ColorClass ColorClass,
C.Subject,
c.CorrespondenceFormula,
C.InternalSenderEntityId,
C.InternalRecipientEntityId,
C.[Sequence] [Sequence],
C.Year,
C.CompletionStatus Status,
Null Number,
(CASE WHEN (
(
(A.ActionDeadlineDate IS NOT NULL AND A.ActionDeadlineDate < @Now)
OR
(C.CorrespondenceDeadlineDate IS NOT NULL AND C.CorrespondenceDeadlineDate < @Now)
)
AND
C.[Closed-Archived] = 0) THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) IsLate,
CAST(0 AS BIT) HasAnyEvents,
C.CreatedByUserId,
CreatedByUser.EmployeeName CreatedByUserName,
CAST(C.CorrespondenceDate AS VARCHAR(50)) CorrDate,
C.CorrespondenceDate,
C.[Closed-Archived] ClosedArchived,
C.IsSaved SavedActionTaken,
((CASE WHEN C.Important = 1 THEN CASE WHEN @IsEnglish = 1 THEN N'Important' ELSE N'هامة' END ELSE '' END) + (CASE WHEN C.Important = 1 AND C.UrgencyID <> 0 THEN CASE WHEN @IsEnglish = 1 THEN N' and ' ELSE N' و ' END ELSE '' END) + (CASE WHEN C.UrgencyID <> 0 THEN (CASE when @IsEnglish = 1 then U.TextEN else U.TextAR end) ELSE '' END)) ImportantUrgencyText,
CAST(C.IsAutoSaved AS BIT) IsAutoSaved,
-- *******************************************************************
rem.ReminderDate as CorrespondenceReminderDateTime,
remAction.ReminderDate as ActionReminderDateTime
FROM (
SELECT * FROM Correspondences CC
WHERE CC.IsDeleted = 0
AND CC.LetterCorrespondenceId IS NULL
AND (CC.ConfidentialityId IN (SELECT [Value] FROM SplitCommaUniqueValues(@ConfidentialityIds)))
AND
( @IsPrivate = 0 OR
(
@IsPrivate = 1 AND CC.IsForPresident = 1
)
)
AND
(
(CC.IsSaved = case when @IsSaved =1 then 1 else CC.IsSaved end)
)
AND (@appModuleId = 0 OR CC.AppModuleId = @appModuleId)
AND (CC.UrgencyID IN (SELECT value FROM SplitCommaUniqueValues(@UrgencyIds)))
AND (CC.Important IN (SELECT value FROM SplitCommaUniqueValues(@Importantance)))
AND CC.CompletionStatus IN(SELECT value FROM SplitComma(@Statuses))
) C
LEFT JOIN CorrespondenceExtendedDetails CorrExt
ON CorrExt.CorrespondenceID = C.CorrespondenceID
LEFT JOIN CorrespondenceActions A
ON C.CorrespondenceID = A.CorrespondenceID
AND A.IsDeleted = 0
AND A.ActionTypeID != 7 -- إنهاء التذكير
LEFT JOIN CorrespondenceActionRecipients R
ON A.CorrespondenceActionID = R.CorrespondenceActionID
AND (
R.AsCopy = 1
)
JOIN Urgencies U
ON C.UrgencyID = U.ID
JOIN ActionTypes ATypes
ON A.ActionTypeID = ATypes.ID
JOIN CorrespondenceCategories CCat
ON C.CorrespondenceCategoryId = CCat.ID
JOIN Confidentialities Confid
ON C.ConfidentialityID = Confid.ID
LEFT JOIN Users ActionCreatedByUser
ON A.ActionCreatedByUserID = ActionCreatedByUser.UserId
LEFT JOIN Users WithDelegateFromUser
ON A.WithDelegateFromUserID = WithDelegateFromUser.UserID
LEFT JOIN Entities SentByEntity
ON A.ActionCreatedByUserEntityId = SentByEntity.EntityID
LEFT JOIN Users SentToUser
ON R.UserId = SentToUser.UserId
LEFT JOIN Entities SentToEntity
ON R.EntityID = SentToEntity.EntityID
LEFT JOIN Users OwnerUser
ON C.OwnerUserID = OwnerUser.UserId
LEFT JOIN Users CreatedByUser
ON C.CreatedByUserID = CreatedByUser.UserId
LEFT JOIN MarkAsReads MR
ON R.CorrespondenceActionRecipientID = MR.CorrespondenceActionRecipientID
AND MR.UserId = @UserId
OUTER APPLY
(
SELECT TOP 1 1 IsFollowedByUser
FROM CorrespondenceFollowups CF
WHERE CF.CorrespondenceId = C.CorrespondenceID
AND CF.UserId = @UserId
AND CF.AssignedByUserId IS NULL
) FollowedByUser
-- *******************************************************************
LEFT JOIN LinkedCorrespondenceSchedules CS on CS.CorrespondenceID = C.CorrespondenceID
LEFT JOIN Reminder rem on rem.ReferenceId=C.CorrespondenceID AND rem.ReferenceType = 1 AND rem.CreatedByUserId=@UserId AND (rem.[Status] = 1 OR rem.[Status] = 2)
Left JOIN Reminder remAction on remAction.ReferenceId = A.CorrespondenceActionID AND remAction.ReferenceType = 2 AND remAction.CreatedByUserId=@UserId AND (remAction.[Status] = 1 OR remAction.[Status] = 2)
-- *******************************************************************
WHERE (
(C.CorrespondenceCategoryId IN (SELECT Value FROM SplitComma(@CorrespondenceCategoryIds)) AND CorrExt.CorrespondenceExtendedCategoryId IS NULL)
OR (CorrExt.CorrespondenceExtendedCategoryId IN (SELECT Value FROM SplitComma(@CorrespondenceExtendedCategoryIds)))
)
AND
(
-- Personal
(
(
(@IsImpersonated = 0 AND R.UserId = @UserId)
OR
(@IsImpersonated = 1 AND R.UserId = @UserId AND @isPersonalDelegationAvailable = 1)
)
AND R.RecipientType = 1 AND R.UserId Is Not null
)
OR
-- Me as Manager (Impersonation mode handled from code by sending the proper Entity Ids.
(
(R.EntityID IN (SELECT Value FROM @tblEntities) AND R.EntityID Is Not null AND R.RecipientType != 1)
)
)
AND C.[Closed-Archived] = Case When @showArchivedInCCInbox = 1 Then 0 Else C.[Closed-Archived] End
AND R.UserTokeAction = 0
AND NOT EXISTS (
SELECT 1 FROM Correspondences CC
INNER JOIN CorrespondenceLinks CL
ON CC.CorrespondenceID = CL.LinkedCorrespondenceID AND CC.CorrespondenceID = C.CorrespondenceID AND CL.LinkTypeID = @IsBundled
)
) T
WHERE T.LetterCorrespondenceId is null
) as ttt
) K where CorrId = 1
)N where (@ApplyPageFilter = 0 OR ( RowIndex > @lFirstRec AND RowIndex < @lLastRec))
Order by
ActionDate DESC, CorrespondenceDate
option(recompile)
END