optimize complex stored procedure - sql

I have a very complex stored procedure and i am not that strong in SQL, please any one who has a strong SQL expertise and can help me optimize or at least can give me a hint, the procedure selects the inbox messages from database for specific user and it contains many other parameters such as paging and categories and also language input and many other details:
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

Related

"IN Clause" causing "is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

I am having difficulty getting past this error message.
This query works:
declare
#warehouseID int =-1,
#type int=2, --0 = all; 1 = serial;2 = nonserial
#LocationID int =0
SELECT Sum(Quantity) AS Quantity,
WarehouseName,
WarehouseID,
sil.Location,
max(si.RecordID) as test,
min(si.RecordID) as test2,
-- (SELECT max(TransactionDate) from SS_Inventory_History sih2 where sih2.InventoryID in (SI.RecordID)
-- )
-- as test4,
(select max(Case When Serial_Number>'' Then COALESCE(si.SoldDate,'') else sih.TransactionDate end ) AS SoldDate
FROM SS_Inventory SI
JOIN SS_Inventory_Location SIL ON SIL.RecordID=SI.LocationID
LEFT JOIN SS_Inventory_Warehouse SIW ON SIW.RecordID =SIL.WarehouseID
Join SS_Inventory_History sih on InventoryID =sih.RecordID and sih.configStage = 7
WHERE
SIL.WarehouseID = CASE WHEN #warehouseID = -1 THEN SIL.WarehouseID ELSE #warehouseID END
AND SI.LocationID = CASE WHEN #LocationID = 0 THEN SI.LocationID ELSE #LocationID END
AND ((si.Quantity=0 and Serial_Number>'') or (Serial_Number=''))
and SIL.Active=1
AND (
(#type = 0 ) OR
(#type = 1 AND Serial_Number > '') OR
(#type = 2 AND COALESCE(Serial_Number,'')='')
)
) AS SoldDate,
max(si.ReceivedDate) AS ReceivedDate
FROM SS_Inventory SI
JOIN SS_Inventory_Location SIL ON SIL.RecordID=SI.LocationID
LEFT JOIN SS_Inventory_Warehouse SIW ON SIW.RecordID =SIL.WarehouseID
WHERE
SIL.WarehouseID = CASE WHEN #warehouseID = -1 THEN SIL.WarehouseID ELSE #warehouseID END
AND SI.LocationID = CASE WHEN #LocationID = 0 THEN SI.LocationID ELSE #LocationID END
AND Quantity>0
and SIL.Active=1
AND (
(#type = 0 ) OR
(#type = 1 AND Serial_Number > '') OR
(#type = 2 AND COALESCE(Serial_Number,'')='')
)
GROUP BY WarehouseName,
WarehouseID,
Location,
Part_Number,
Dist_Part_Num
but when i add/uncomment
(SELECT max(TransactionDate) from SS_Inventory_History sih2 where sih2.InventoryID in (SI.RecordID)
)
as test4,
so that it looks like
declare
#warehouseID int =-1,
#type int=2, --0 = all; 1 = serial;2 = nonserial
#LocationID int =0
SELECT Sum(Quantity) AS Quantity,
WarehouseName,
WarehouseID,
sil.Location,
--delete me?
max(si.RecordID) as test,
min(si.RecordID) as test2,
(SELECT max(TransactionDate) from SS_Inventory_History sih2 where sih2.InventoryID in (SI.RecordID)
)
as test4,
(select max(Case When Serial_Number>'' Then COALESCE(si.SoldDate,'') else sih.TransactionDate end ) AS SoldDate
FROM SS_Inventory SI
JOIN SS_Inventory_Location SIL ON SIL.RecordID=SI.LocationID
LEFT JOIN SS_Inventory_Warehouse SIW ON SIW.RecordID =SIL.WarehouseID
Join SS_Inventory_History sih on InventoryID =sih.RecordID and sih.configStage = 7
WHERE
SIL.WarehouseID = CASE WHEN #warehouseID = -1 THEN SIL.WarehouseID ELSE #warehouseID END
AND SI.LocationID = CASE WHEN #LocationID = 0 THEN SI.LocationID ELSE #LocationID END
AND ((si.Quantity=0 and Serial_Number>'') or (Serial_Number=''))
and SIL.Active=1
AND (
(#type = 0 ) OR
(#type = 1 AND Serial_Number > '') OR
(#type = 2 AND COALESCE(Serial_Number,'')='')
)
) AS SoldDate,
max(si.ReceivedDate) AS ReceivedDate
FROM SS_Inventory SI
JOIN SS_Inventory_Location SIL ON SIL.RecordID=SI.LocationID
LEFT JOIN SS_Inventory_Warehouse SIW ON SIW.RecordID =SIL.WarehouseID
WHERE
SIL.WarehouseID = CASE WHEN #warehouseID = -1 THEN SIL.WarehouseID ELSE #warehouseID END
AND SI.LocationID = CASE WHEN #LocationID = 0 THEN SI.LocationID ELSE #LocationID END
AND Quantity>0
and SIL.Active=1
AND (
(#type = 0 ) OR
(#type = 1 AND Serial_Number > '') OR
(#type = 2 AND COALESCE(Serial_Number,'')='')
)
GROUP BY WarehouseName,
WarehouseID,
Location,
Part_Number,
Dist_Part_Num
I get this error message:
Msg 8120, Level 16, State 1, Line 15
Column 'SS_Inventory.RecordID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Does anyone have any idea what I am doing wrong?

Invalid column error in SQL Server 2008

I am trying to run the following query,
DECLARE #p_UserName as nvarchar(100)
DECLARE #p_Department as int
DECLARE #p_Section as int
DECLARE #p_SubSection as int
DECLARE #p_PermissionGroup as int
DECLARE #p_DistributionGroup as int
DECLARE #p_Permission as nvarchar(100)
DECLARE #p_IfPerChecked as bit
DECLARE #p_Role as int
SET #p_UserName = ''
SET #p_Department = NULL
SET #p_Section = NULL
SET #p_SubSection = NULL
SET #p_PermissionGroup = NULL
SET #p_DistributionGroup = NULL
SET #p_Permission = ''
SET #p_Role = NULL
SELECT Users.EnglishName,
(SELECT Designation.TitleEnglish FROM Designation WHERE Users.Designation = Designation.ID) AS [Role],
(SELECT Department.TitleEnglish FROM Department WHERE Users.DepartmentID = Department.ID) AS [Department],
(SELECT Section.TitleEnglish FROM Section WHERE Users.SectionID = Section.SectionID) AS [Section],
(SELECT SubSection.TitleEnglish FROM SubSection WHERE Users.SubSectionID = SubSection.SubSectionID) AS [Sub-Section],
(SELECT Groups.TitleEnglish FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 0
) AS [Permissions Group],
(SELECT Groups.TitleEnglish FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 1
) AS [Distribution Group],
(CASE
WHEN Users.ApplyUserRights = 1 THEN dbo.fn_GetUserPermissions('Users', Users.UserID)
WHEN Users.ApplyUserRights = 0 THEN dbo.fn_GetUserPermissions('Groups', (SELECT GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID))
END) AS [Permissions]
FROM Users WHERE
((#p_UserName <> NULL OR #p_UserName <> '') AND #p_UserName = Users.UserName) OR
((#p_Department <> NULL OR #p_Department <> 0) AND #p_Department = Users.DepartmentID) OR
((#p_Section <> NULL OR #p_Section <> 0) AND #p_Section = Users.SectionID) OR
((#p_SubSection <> NULL OR #p_SubSection <> 0) AND #p_SubSection = Users.SubSectionID) OR
((#p_PermissionGroup <> NULL OR #p_PermissionGroup <> 0) AND #p_PermissionGroup = (
SELECT Groups.GroupID FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 0
)) OR
((#p_DistributionGroup <> NULL OR #p_DistributionGroup <> 0) AND #p_DistributionGroup = (
SELECT Groups.GroupID FROM Groups WHERE
(SELECT UserRights.GroupID FROM UserRights WHERE Users.UserID = UserRights.UserID) = Groups.GroupID
AND Groups.IsDistribution = 1
)) OR
(1 = CASE
WHEN Users.ApplyUserRights = 1 AND #p_Permission = 'AllowChangePassword' THEN 0
ELSE dbo.fn_CheckPemission(#p_Permission, UserID)
END) OR
((#p_Role <> NULL OR #p_Role <> 0) AND #p_Role = Users.Designation) OR
(1 = 1)
GROUP BY CASE #GroupBy
WHEN 'DepartmentID' THEN Users.DepartmentID
WHEN 'SectionID' THEN Users.SectionID
WHEN 'SubSectionID' THEN Users.SubSectionID
ELSE Users.EnglishName
END
And I keep getting the error
Column 'Users.EnglishName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Please help!
Like the message states, you need to group by the EnglishName column unless it is used in an aggregate function(Max or sum or likewise).
The issue is evident from your error message. Use GROUP BY in case of aggregate functions.

Join unique ID's from another table

Here is the story: I have to implement filter. And in this filter there are certain categories I filter by.
One of the filters is "favourite" filter (#includeFavourites ).
I have this huge SQL with paging and sorting and everything.
Now, when "includeFavourites" option in filter is clicked, then I also have to select unique ID's from different table (this entries are stored in different datatable), where favourites are stored.
I have tried left outer join, but it returns "number of favourites" records for each record in primary table. Coalesce didn't help at all.
Here is my SQL:
--this is needed because stored procedure must know how many days are selected
DECLARE #daysCount int
SET #daysCount = 0
IF (#mon IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#tue IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#wed IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#thu IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#fri IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sat IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sun IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
-- Insert statements for procedure here
SELECT * FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy = 'NA' THEN title END,
CASE WHEN #OrderBy = '' THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS Row,
Articles.ArticleId, Articles.userId, Articles.timestamp as datePosted, users.screenName,
defaultSmallImagePath, authorRating, ArticleCosts, title,
FROM Articles
LEFT OUTER JOIN
Users on Articles.userId = Users.userId
LEFT OUTER JOIN
ArticleAdditionalInformation ON ArticleAdditionalInformation.ArticleId = Articles.ArticleId
--JOIN FOR CONTINENT
LEFT OUTER JOIN
Codings as Continent ON Continent.codingKeyId = ArticleAdditionalInformation.continentId AND Continent.languageId = #languageId
-- JOIN FOR COUNTRY
LEFT OUTER JOIN
CodingsAssociated as Country ON Country.codingKeyId = ArticleAdditionalInformation.countryId AND Country.languageId = #languageId
-- JOIN FOR Article TRANSLATION DATA
LEFT OUTER JOIN
ArticlesTranslations ON ArticlesTranslations.ArticleId = Articles.ArticleId AND ArticlesTranslations.languageId=#languageId
LEFT OUTER JOIN
ArticleCategories ON ArticleCategories.ArticleId = Articles.ArticleId
WHERE
(
ArticleCategories.categorieId =1 OR ArticleCategories.categorieId =2 OR
ArticleCategories.categorieId =3 OR ArticleCategories.categorieId =4 OR
ArticleCategories.categorieId = 5
) AND
(ArticlesTranslations.title LIKE '%' + #searchString + '%' OR #searchString IS NULL)
-- COST filter
AND
(ArticleCosts < #cost OR #cost = 0)
AND
(ArticleCosts > 0 OR #cost = 0)
--END cost filter
-- EXCLUDE already stored for selected days
AND Articles.ArticleId -- exclude these ArticleIds
NOT IN
(
SELECT DailyContent.ArticleId
FROM DailyContent
WHERE
sectionId=#sectionId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
GROUP BY
DailyContent.ArticleId
HAVING
(COUNT(sectionId) = #daysCount)
)
-- END exclude
) p
WHERE (Row > #startRowIndex AND Row <=#startRowIndex + #pageSize)
ORDER BY Row
END
So, I would only like to include unique articleIds from favourite table, when #includeFavourites parameter is not null.
Any hint would be greatly appreciated ;)
I am using SQL server 2008.
Try this one -
DECLARE #daysCount INT
SELECT #daysCount =
ISNULL(#mon, 0) + -- if #mon = 1, #tue = 2, .... 1 + (2-1)=1 + (3-2)=1 + ...
ISNULL(#tue - 1, 0) +
ISNULL(#wed - 2, 0) +
ISNULL(#thu - 3, 0) +
ISNULL(#fri - 4, 0) +
ISNULL(#sat - 5, 0) +
ISNULL(#sun - 6, 0)
SELECT *
FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy IN ('NA', '') THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS [Row]
, a.ArticleId
, a.userId
, a.[timestamp] as datePosted
, u.screenName
, defaultSmallImagePath
, authorRating
, ArticleCosts
, title
FROM dbo.Articles a -- always use schema and alias
LEFT JOIN dbo.Users u on a.userId = u.userId -- OUTER is unnecessary
LEFT JOIN dbo.ArticleAdditionalInformation aai ON aai.ArticleId = a.ArticleId
LEFT JOIN dbo.Codings cd ON cd.codingKeyId = aai.continentId AND cd.languageId = #languageId
LEFT JOIN dbo.CodingsAssociated c ON c.codingKeyId = aai.countryId AND c.languageId = #languageId
LEFT JOIN dbo.ArticlesTranslations at ON at.ArticleId = a.ArticleId AND at.languageId = #languageId
LEFT JOIN dbo.ArticleCategories ac ON ac.ArticleId = a.ArticleId
WHERE ac.categorieId IN (1, 2, 3, 4, 5)
AND (
at.title LIKE '%' + #searchString + '%'
OR
#searchString IS NULL
)
AND (ArticleCosts < #cost OR #cost = 0)
AND (ArticleCosts > 0 OR #cost = 0)
AND a.ArticleId NOT IN (
SELECT dc2.ArticleId
FROM dbo.DailyContent dc2
WHERE sectionId = #sectionId
AND (
weekDayId % #daysCount = 0 -- possible it's works
--weekDayId = #mon OR
--weekDayId = #tue OR
--weekDayId = #wed OR
--weekDayId = #thu OR
--weekDayId = #fri OR
--weekDayId = #sat OR
--weekDayId = #sun
)
GROUP BY dc2.ArticleId
HAVING COUNT(sectionId) = #daysCount
)
) p
WHERE [Row] BETWEEN #startRowIndex AND #startRowIndex + #pageSize
--ORDER BY [Row] -- ROW_COUNT already sorted your rows

how to set default value in a output parameter

in my following query i want to set 0, 0, 0 in #TMarks, #OMarks, #Percentage respectively if the select statement used with them returns nothing
create procedure [dbo].[TestRecordSelectMInfo]
#GRNo varchar(4),
#SessionId numeric(1),
#TestTypeId numeric(1),
#TMarks int output,
#OMarks numeric(4) output,
#Percentage numeric(4) output,
#Grade varchar(4) output
as
begin
SELECT Subjects.Subject, Marks.TotalMarks, Marks.PassingMarks, TestRecord.Marks, Result = case when TestRecord.Marks = 'A' then 'A' else case when cast(TestRecord.Marks as numeric) < Marks.PassingMarks then 'F' else 'P' end end FROM Subjects INNER JOIN Marks ON Subjects.SubjectId = Marks.SubjectId INNER JOIN TestRecord ON Subjects.SubjectId = TestRecord.SubjectId AND Marks.TestTypeId = TestRecord.TestTypeId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRno
set #TMarks = (select sum(Marks.TotalMarks) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks )
set #OMarks = (select sum(cast(TestRecord.Marks as numeric)) from Marks inner join TestRecord on Marks.TestTypeId = TestRecord.TestTypeId and Marks.SubjectId = TestRecord.SubjectId where TestRecord.SessionId = #SessionId and TestRecord.TestTypeId = #TestTypeId and TestRecord.GRNo = #GRNo and TestRecord.Marks <> 'A' and cast(TestRecord.Marks as numeric) > Marks.PassingMarks)
set #Percentage = #OMarks / #TMarks * 100;
set #Grade = case
when #Percentage < 50
then
'NIL'
else
case
when #Percentage < 60
then
'C'
else
case
when #Percentage < 70
then
'B'
else
case
when #Percentage < 80
then
'A'
else
case
when #Percentage <= 100
then
'A+'
else
'FAIL'
end
end
end
end
end
end
GO
EDIT: An aggregate without a group by returns null for an empty set. You could work around this with insull:
select #TMarks = IsNull(sum(Marks.TotalMarks),0)
from Marks
inner join TestRecord
on Marks.TestTypeId = TestRecord.TestTypeId
and Marks.SubjectId = TestRecord.SubjectId
where TestRecord.SessionId = #SessionId
and TestRecord.TestTypeId = #TestTypeId
and TestRecord.GRNo = #GRNo
and TestRecord.Marks <> 'A'
and cast(TestRecord.Marks as numeric) > Marks.PassingMarks

Create Clustered/Non Clustered Index in view

I am having a view which returns value to a table. The process takes a long time... So I felt it works better if go for indexing on view. Can anyone plz guide me to add index to view.
ALTER View [dbo].[GetApplicationBudgetAndUtilized]
as
Select *, (convert(money,isnull(TotalBudget,0)) - convert(money,isnull(Utilized,0))) as [Left] from (
SELECT Distinct PM.PKID AS ProgramID, F.PKID as FundID, I.PKID as ProjectID,
MYB.PKID AS MultiYearBudgetID,
(Select Isnull(Sum(IsNull(PBC1.BudgetAmount,0)),0) from ProgramBudgetConfiguration PBC1
Where pbc1.MultiYearBgtIdFkId = pbc.MultiYearBgtIdFkId and PBC1.IsActive = 1 and LOVBudgetTypeIDFKID = 'BT_INC' group
by pbc1.MultiYearBgtIdFkId) AS TotalProgramBudget,
App.TotalBudget,
I.PKID,
(Case when exists (Select 'x' from InstallationTransactionHeader Where ParentPrjNumber = I.PKID and IsDelete = 0)
then
(case
when not exists (select cast(isnull(I1.CustInstallIncAmt,0.00) + isnull(I1.SPInstIncentiveAmt,0.00) + isnull(I1.ThirdPartyIncentive,0.00) as Money)
from InstallationTransactionHeader I1 where I1.ParentPrjNumber is not null and I1.StatusFKID in ('ITS_SUB','ITS_APP','ITS_VRF') and
I1.ParentPrjNumber = I.PKID and I1.FundRequestIDFKID is not null) then (select '0')
else
(select isnull(sum(cast(isnull(I1.CustInstallIncAmt,0.00) + isnull(I1.SPInstIncentiveAmt,0.00) + isnull(I1.ThirdPartyIncentive,0.00) as Money)),0)
from InstallationTransactionheader I1 where I1.StatusFKID in ('ITS_SUB','ITS_APP','ITS_VRF') and I1.ParentPrjNumber is not null and
I1.ParentPrjNumber = I.PKID and I1.isdelete = 0 and I1.FundRequestIDFKID is not null group by I1.parentPrjNumber)
End)
else
--isnull(cast(isnull(I.CustInstallIncAmt,0.00) + isnull(I.SPInstIncentiveAmt,0.00) + isnull(I.ThirdPartyIncentive,0.00) as Money),0)
(case
when not exists (select isnull(cast(isnull(I.CustInstallIncAmt,0.00) + isnull(I.SPInstIncentiveAmt,0.00) + isnull(I.ThirdPartyIncentive,0.00) as Money),0) from
InstallationTransactionHeader I where StatusFKID in ('ITS_SUB','ITS_APP','ITS_VRF') and IsDelete = 0 and
PKID = I.PKID and I.FundRequestIDFKID is not null) then 0--(select '0')
else
(select isnull(sum(cast(isnull(I1.CustInstallIncAmt,0.00) + isnull(I1.SPInstIncentiveAmt,0.00) + isnull(I1.ThirdPartyIncentive,0.00) as Money)),0)
from InstallationTransactionheader I1 where I1.StatusFKID in ('ITS_SUB','ITS_APP','ITS_VRF') and IsDelete = 0 and I1.FundRequestIDFKID is not null and
PKID = I.PKID)
End)
End) as Utilized
--Cast(App.TotalBudget - (isnull(I.CustInstallIncAmt,0.00) + isnull(I.SPInstIncentiveAmt,0.00) + isnull(I.ThirdPartyIncentive,0.00)) as Money) as [Left]
FROM
( SELECT PKID as FundID, ProgramID AS ProgramID, (ISNULL(IncentiveAmount,0.00) + ISNULL(CustInstallIncAmt, 0.00) + ISNULL(SPInstIncentiveAmt, 0.00) ) AS TotalBudget
FROM dbo.FundRequestHeader AS F WHERE (IsDelete = 0) AND (IsActive = 1) AND (StatusFKID in ('IAS_APP','IAS_CAN'))) AS App
INNER JOIN dbo.ProgramMaster AS PM
INNER JOIN dbo.MultiYearBudget AS MYB ON PM.PKID = MYB.ProgramIDFKID
INNER JOIN dbo.ProgramBudgetConfiguration AS PBC ON MYB.PKID = PBC.MultiYearBgtIdFkId ON App.ProgramID = PM.PKID
INNER JOIN dbo.FundRequestHeader AS F ON F.PKID = App.FundID
INNER JOIN dbo.InstallationTransactionHeader AS I ON I.FundRequestIDFKID = F.PKID
WHERE (PM.IsActive = 1) AND (MYB.IsActive = 1) AND (PBC.IsActive = 1) AND
(PBC.LOVBudgetTypeIDFKID = 'BT_INC') And (F.StatusFKID in ('IAS_APP','IAS_CAN'))
--and (1=case when(select ProgramTypeIDFKID from InstallationTransactionHEader where ProgramTypeIDFKID='IT_PRE' and ParentPrjNumber is null and PaymentSchedule=1)='IT_PRE' then 0 else 1 end)
--and I.ProgramTypeIDFKID <> 'IT_PRE' or I.PaymentSchedule = 0 or (I.ProgramTypeIDFKID = 'IT_PRE' and I.PaymentSchedule = 1 and I.ParentPrjNumber is not null)
and MYB.PKID = F.BudgetPeriodID and ((MYB.IsActive = 1))-- or ((MYB.status = 0) and F.StatusFKID ='IAS_APP'))
and (MYB.Status = 1 or (MYB.Status =(case when exists(select M.status from MultiYearBudget M, FundRequestHeader F
where F.ProgramID=M.ProgramIDFKID and F.ProgramTypeIDFKID <>'IT_FCFS' and M.Pkid=F.BudgetPeriodID
and F.StatusFKID='IAS_APP' and F.ProgramID=PM.PKID and M.Status=0 )then 0 else 1 end))
)
)temp
GO
Indexed views have certain limitations
In your case, I can immediately see some blockers
SELECT *
Derived tables
So read this article, and see how far you get...
However, you should be able to look the execution plan identify bottlenecks where you can add indexes to the bases tables