SP executing error - sql

I am writing below SP.But when i try to run this query i am getting this error:
There is already an object named
'#myCourses1' in the database.
So this getting in two else loops. also
create proc [dbo].[GetOrdersByUserIDwithSubscription]
(
#UserID int
)
as
begin
declare #status varchar(500)
declare #substatus char(2)
select #substatus=Subscribe_status from tbl_user where userid=#userid
print #substatus
if #substatus='N'
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID and c.courseprice<>'subscriber'
Order By CategoryText, CourseTitle
END
else if #substatus=''
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID and c.courseprice<>'subscriber'
Order By CategoryText, CourseTitle
END
else if #substatus='Y'
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID
Order By CategoryText, CourseTitle
END

The SQL Parser is choking because you have used the same temp table name in different parts of the IF statement. The IF does not have scope like other programming languages.
If you do not need to reference the temp table outside of each of the IF blocks you can get around the problem by using a different table name in each part.
Have a look at my answer to a similar question.

Also, the monstrocity of a query you have could be reduced to this:
create proc [dbo].[GetOrdersByUserIDwithSubscription](
#UserID int
)
as
begin
declare #substatus char(2)
select #substatus = Subscribe_status
from tbl_user
where userid = #userid
select a.*, b.CategoryText,
Cast("" as Varchar(10)) as SectionsViewed,
PurchasedDate as dateadded
from dbo.Tbl_CourseInformations a
join Tbl_Categories b ON a.AssignCategory = b.CategoryID
join Tbl_Orders c ON c.UserID = #UserID
and c.CourseID = a.CourseID
and (#substatus = 'N' or c.courseprice <> 'subscriber')
order by CategoryText, CourseTitle
END

Explicitly create the temp table at the beginning of the proc.
CREATE TABLE #myCourses1 (
...
)
Then write your SELECT statements as:
INSERT INTO #myCourses1
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded
from dbo.Tbl_CourseInformations
...

You syntax is
SELECT [Column-List] INTO #TempTable FROM [Rest-of-Query]
When using this syntax, Sql Server attempts to create #TempTable on the fly based on your column list (source).
To get around this, either Drop #TempTable at the beginning of the stored procedure (if you do not need its data beyond the scope of the SP), or make it a permanent table.

Related

Replacing Is Null Or Exist Inner Query Logic to Reduce Stored Procedure Execution Time

My stored procedure is currently using Is Null Or Exist logic combined with an inner query to filter out the records. The stored procedure is converting multiple comma-separated input values to temp tables (in the production scenario, the input record count will be much higher). And the inner query is using these temp tables for filter conditions. Due to the concern over query execution time would like to change the existing inner-query with an alternate (like left join). But need to retain the same Is Null Or Exist logic. Any suggestions?
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
WHERE (#SelectedOfferes IS NULL
OR (EXISTS (SELECT 1 FROM #SelectedOfferes OFR
WHERE OFR.DiscountCode = P.DiscountCode)))
AND (#SelectedBrandCode IS NULL
OR (EXISTS (SELECT 1 FROM #BrandCode BC
WHERE BC.BrandCode = P.BrandCode)))
AND (#CategoryCode IS NULL
OR (EXISTS (SELECT 1 FROM #CategoryCode CAT
WHERE CAT.CategoryCode = P.CategoryCode)))
Dynamic SQL version
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
The below example should work the same as what you supplied but should be faster since it removes the ORs and the correlated subqueries from the WHERE clause. I'm not a fan of using dynamic SQL but sometimes it is the best way to get the job done. Maybe someone else can come up with a non-dynamic solution that works as well or better.
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
DECLARE #SQL NVarchar(4000);
SET #SQL = N'SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode'
IF #SelectedOfferes IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode';
IF #SelectedBrandCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode';
IF #CategoryCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode';
EXEC sys.sp_executesql #stmt = #SQL;
This method doesn't quite do what the OP wanted but is valid in many other cases
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
But either way the below change to your last query should help quite a bit. The IS NULL parts aren't needed since it is a LEFT JOIN and the table will be empty if the variable it is built with is NULL, so you get the same result with less work for the engine.
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
LEFT JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode
LEFT JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode
LEFT JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode

How to show output for group of people instead of single individual?

I have written this code to show the FEE PAID, PENDING etc for an individual student but actually it was supposed to be for the whole class of students. I tried a lot but can't do it for the whole class. How to do this ? Ignore #studentID, I just want it for #ClassID.
ALTER PROCEDURE [Accounts].[GetUserPaymentsPartialRecord]
#StudentId INT= 14,
#classID int=1
AS
BEGIN
declare #accID int
set #accID= (select st.Account_ID from School.StudentInformation ST where st.StudentID = #StudentId and st.ClassToWhichAdmitted_ID= #classID)
declare #className varchar(50)
Set #className= (Select c.ClassName from School.Classes c
Inner Join School.StudentInformation si
ON si.ClassToWhichAdmitted_ID= c.ClassID where si.StudentID= #StudentId)
declare #transactions varchar(max)
Set #transactions=(select convert(varchar,Convert(decimal(10,0),t.Credit))+', ' AS 'data()' from Accounts.Transactions T
where t.Account_ID = (#accID)
and
t.Credit>0
AND
t.IsReversed=0
AND
t.InvoiceNumber in(Select inv.InvoiceNumber from Accounts.Invoices inv where inv.Student_ID= #StudentId)
AND
Particulars Like '%Received%'
FOR XML PATH(''))
declare #PayableAmount money
set #PayableAmount = (select sum(i.Amount+ i.Fine) from Accounts.Invoices I where I.Student_ID= #StudentId and i.Class_ID = #classID )
declare #TotalAmountPaid money
Set #TotalAmountPaid= (Select sum(t.Credit) from Accounts.Transactions T
where t.Account_ID = (#accID)
and
t.Credit>0
AND
t.IsReversed=0
AND
t.InvoiceNumber in(Select inv.InvoiceNumber from Accounts.Invoices inv where inv.Student_ID= #StudentId)
AND
t.Particulars Like '%Received%'
group by t.Account_ID)
declare #PendingAmount money
Set #PendingAmount= (#PayableAmount - #TotalAmountPaid)
SELECT st.StudentName, st.StudentRegisterationNo,#className as ClassName,
#transactions as Paid, Convert(decimal(10,0),#TotalAmountPaid) as TotalPaid,
#PayableAmount, #PendingAmount as 'PendingAmount' FROM School.StudentInformation ST
where st.StudentID= #StudentId
END
You can try to move the above procedure which is at student and class level to simply as a tabular set which can be queried at class level
See sample proc below:
CREATE PROCEDURE [Accounts].[GetUserPaymentsPartialRecordByClass]
#classID int=1
AS
BEGIN
create table #temp (sID int,cID int, accID int, className varchar(50),transactions varchar(max),PayableAmount money,TotalAmountPaid money,PendingAmount money)
INSERT into #temp
(sID,cID,accID,className)
select
distinct st.StudentID as sID,
st.ClassToWhichAdmitted_ID as cID ,
st.Account_ID as accID,
c.ClassName as className
from School.StudentInformation st
left join School.Classes c
on st.ClassToWhichAdmitted_ID= c.ClassID
where st.ClassToWhichAdmitted_ID= #classID
update temp
set temp.transactions=transactions
from #temp temp outer apply(
select convert(varchar,Convert(decimal(10,0),t.Credit))+', ' AS 'data()'
from Accounts.Transactions T
on T.Account_ID=temp.accID
and T.Credit>0 and T.IsReversed=0
and Particulars Like '%Received%'
inner join Accounts.Invoices inv
on inv.Student_ID=temp.sID and inv.InvoiceNumber=T.InvoiceNumber
FOR XML PATH('')
) s(transactions)
update T
set PayableAmount = sum(i.Amount+ i.Fine)
from #temp T
INNER JOIN Accounts.Invoices I ON I.Student_ID= T.sId and i.Class_ID = T.cID
update temp
set TotalAmountPaid =sum(t.Credit) from
#temp temp Inner join
Accounts.Transactions T
on t.Account_ID = temp.accID
and t.Credit>0 AND t.IsReversed=0 and
t.Particulars Like '%Received%'
inner join Accounts.Invoices inv
on inv.Student_ID=temp.sID and inv.InvoiceNumber=T.InvoiceNumber
group by T.Account_ID
update temp
sett PendingAmount= (PayableAmount - TotalAmountPaid)
SELECT st.StudentName, st.StudentRegisterationNo,ClassName,
transactions as Paid, Convert(decimal(10,0),TotalAmountPaid) as TotalPaid,
PayableAmount, PendingAmount as 'PendingAmount' FROM #temp T inner join School.StudentInformation ST
On st.StudentID= T.sId
END

Best way get complex sql data(Performance issue)

Hi i have a timeLogs table having with columns(id,startTime,EndTime,User_Id,Client_Id,Project_Id,Task_Id,TotalHours)
I need output Having columns(Client,Project,Task,NoOfResources,TotalTime) with projectids,taskids,datefrom ,datetill filters Sample output and table structure are shown below
Here User_Id ,Client_Id,Task_Id,Project_Id are foreign keys with users,clients,tasks,projects
Here # of resources is user count
I am doing it through a stored procedure:
ALTER procedure [dbo].[GetProjectUtilizationReport]
(#DateFrom datetime =null,
#DateTill datetime = null,
#TaskTypeIds nvarchar(max) = null,
#TaskIds nvarchar(max) = null,
#UserIds nvarchar(max) = null,
#ProjectIds nvarchar(max) = null)
AS
BEGIN
CREATE TABLE #TempTable(id int,
ProjectId int,
ClientId int,
UserId int,
TaskId int,
TotalHours numeric(18,2),
StartTime datetime,
TaskTypeId int)
--- create a temp table with data dump
INSERT INTO #TempTable(Id, ProjectId, ClientId, UserId, TaskId, TotalHours, StartTime, TaskTypeId)
SELECT
tl.id,Project_Id, Client_Id,
User_Id, Task_Id, TotalHours,
StartTime, TaskType_Id
FROM
TimeLogs tl
JOIN
Tasks t ON tl.Task_Id = t.Id
--apply filter to temp table
IF (#DateFrom IS NOT NULL)
DELETE FROM #TempTable
WHERE StartTime < #DateFrom
IF (#DateTill IS NOT NULL)
DELETE FROM #TempTable
WHERE StartTime > #DateTill
IF (#TaskTypeIds IS NOT NULL)
DELETE FROM #TempTable
WHERE TaskTypeId NOT IN (SELECT Item FROM dbo.SplitString(#TaskTypeIds, ','))
IF (#TaskIds IS NOT NULL)
DELETE FROM #TempTable
WHERE TaskId NOT IN (SELECT Item FROM dbo.SplitString(#TaskIds, ','))
IF (#UserIds IS NOT NULL)
DELETE FROM #TempTable
WHERE UserId NOT IN (SELECT Item FROM dbo.SplitString(#UserIds, ','))
IF (#ProjectIds IS NOT NULL)
DELETE FROM #TempTable
WHERE ProjectId NOT IN (SELECT Item FROM dbo.SplitString(#ProjectIds, ','))
--finaly select data
SELECT
p.Name as Project, c.Name as Client,
tl.TaskId, t.Name as Task,
SUM(TotalHours) as Totalhours,
COUNT(DISTINCT tl.UserId) as NoOfResources,
c.Id as ClientId
FROM
#TempTable tl
JOIN
Tasks t ON tl.TaskId = t.Id
JOIN
Clients c ON c.Id = tl.ClientId
JOIN
Projects p ON tl.ProjectId = p.Id
GROUP BY
tl.TaskId, c.id, c.Name, p.Name, t.Name
--drop temp table
DROP TABLE #TempTable
END
I think there may be a much better approach - something like an view etc but I don't have any ideas.
May to put data in other table on insert etc.
Please put your suggestion show that i can get results as fast as posible.
I often try to avoid #tables where I can.
SELECT c.Name AS Client, p.Name AS Project, t.Name AS Task, COUNT(DISTINCT tl.User_Id) AS NoOfResources, SUM(TotalHours) AS Totalhours
FROM TimeLogs tl
INNER JOIN Tasks t ON tl.Task_Id =t.Id
INNER JOIN Clients c ON c.Id =tl.Client_Id
INNER JOIN Projects p ON tl.Project_Id =p.Id
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#UserIds, ''), ',')) users ON users.Item = tl.User_Id OR #UserIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#TaskTypeIds, ''), ',')) tasktypes ON tasktypes.Item = tl.TaskType_Id OR #TaskTypeIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#TaskIds, ''), ',')) tasks ON tasks.Item = tl.Task_Id OR #TaskIds IS NULL
INNER JOIN (SELECT Item FROM dbo.SplitString(ISNULL(#ProjectIds, ''), ',')) projects ON projects.Item = tl.Project_Id OR #ProjectIds IS NULL
WHERE (#DateFrom IS NULL OR StartTime < #DateFrom)
AND (#DateTill IS NULL OR StartTime > #DateTill)
GROUP BY c.Id, c.Name, p,Id, p.Name, t.Id, t.Name

Can we make join between two stored procedures in SQL Server

I have this stored procedure:
CREATE PROCEDURE [dbo].[TestPackageAccept]
AS
BEGIN
SELECT A.Id,
a.PackageNumber,
a.Size,
a.Code,
a.TestPackageOrder,
B.status as LineCheckState,
B.ReportNumber as LineCheckReportNumber,
B.SubmitDateTime as LineCheckSubmitDateTime,
c.status as CleaningState,c.ReportNumber as CleanReportNumber,
c.SubmitDateTime as CleanSubmitDateTime,
c.status as ReInstatement,
d.ReportNumber as ReInstatementReportNumber,
d.SubmitDateTime as ReInstatementSubmitDateTime,
E.status as Flushing,
e.ReportNumber as FlushingReportNumber,
e.SubmitDateTime as FlushingSubmitDateTime,
f.status as Drying,
f.ReportNumber as DryingReportNumber,
f.SubmitDateTime as DryingSubmitDateTime,
m.status as PAD,
m.ReportNumber as PADReportNumber,
m.SubmitDateTime as PADSubmitDateTime,
n.status as Mono,
n.ReportNumber as MonoReportNumber,
n.SubmitDateTime as MonoSubmitDateTime,
p.status as Variation,
p.ReportNumber as VariationReportNumber,
p.SubmitDateTime as VariationSubmitDateTime
FROM TestPackages A
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'LineCheck')) B
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Clean')) C
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Reinstatment'))D
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Flushing')) E
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Drying')) F
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Test')) G
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'PADTest')) M
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Mono')) N
outer Apply (Select * from dbo.ReturnAcceptStepOfTestPackage(A.id,'Variation')) P
END;
And this
CREATE PROCEDURE [dbo].[TestPackageProgress]
AS
BEGIN
SELECT PackageId,
packagenumber,
count(*) as [Total],
sum(case [WeldStatus] when 'Accept' then 1 end) as Accept,
sum(case [WeldStatus] when 'accept' then 0 else 1 end) as Remain,
ROUND(CONVERT(float,sum(case [WeldStatus] when 'Accept' then 1 end))/CONVERT(float,count(*)) * 100,2) as PercentProgress
FROM [SPMS2].[dbo].[JointHistory]
WHERE PackageId is not null
GROUP BY PackageId,PackageNumber;
END;
Can I make a join between these two stored procedure's result sets on first.id = second.packageid?
You can put result sets from both SP into temp tables and then join them:
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
--Here you add all columns from SP output with there datatypes
)
Then you can:
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
The same way for second SP, then join:
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid
Don't forget to DROP temp tables:
DROP TABLE #PackageAccept
DROP TABLE #PackageProgress
The full batch will be like:
IF OBJECT_ID(N'#PackageAccept') IS NOT NULL
BEGIN
DROP TABLE #PackageAccept
END
ELSE
BEGIN
CREATE TABLE #PackageAccept (
Id INT,
PackageNumber INT,
Size INT,
Code NVARCHAR(100),
TestPackageOrder INT
--etc
)
END
IF OBJECT_ID(N'#PackageProgress') IS NOT NULL
BEGIN
DROP TABLE #PackageProgress
END
ELSE
BEGIN
CREATE TABLE #P (
PackageId INT,
packagenumber INT,
[Total] INT,
Accept INT,
Remain INT
--etc
)
END
INSERT INTO #PackageAccept
EXEC [dbo].[TestPackageAccept]
INSERT INTO #PackageProgress
EXEC [dbo].[TestPackageProgress]
SELECT *
FROM #PackageAccept pa
INNER JOIN #PackageProgress pp
ON pa.id = pp.packageid

Returning column with count of 0

I have a query that looks up a list of documents depending on their department and their status.
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.name,
COUNT(*) AS TodayCount
FROM dbo.TableA ILDP
LEFT JOIN dbo.TableB ILDPS ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
LEFT JOIN dbo.TableC ILDPST ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
WHERE (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
AND ILDPS.CurrentStateTypeId IN (
SELECT value
FROM dbo.StringAsIntTable(#StatusIds)
)
GROUP BY ILDPST.name;
This returns the results:
However, I'd also like to be able to return statuses where the TodayCount is equal to 0 (i.e. any status with an id included in #StatusIds should be returned, regardless of TodayCount).
I've tried messing with some unions / joins / ctes but I couldn't quite get it to work. I'm not much of an SQL person so not sure what else to provide that could be useful.
Thanks!
If you want to have all the records from TableC you need to left join all other tables to it, not left join it to the other tables. Also it's best to INNER JOIN the filtering table you create from #StatusIds rather then apply it through INclause. Try this:
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.Name, COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM (SELECT DISTINCT value FROM dbo.StringAsIntTable(#StatusIds)) StatusIds
INNER JOIN dbo.TableC ILDPST
ON ILDPST.IntranetLoanDealPreStateTypeId = StatusIds.value
LEFT JOIN dbo.TableB ILDPS
ON ILDPS.CurrentStateTypeId = ILDPST.IntranetLoanDealPreStateTypeId
LEFT JOIN dbo.TableA ILDP
ON ILDP.IntranetLoanDealPreStateId = ILDPS.IntranetLoanDealPreStateId
AND (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
GROUP BY ILDPST.Name;
Try this instead:
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
DECLARE #DepartmentId NVARCHAR(2) = 'IT';
SELECT ILDPST.name,
COUNT(ILDP.IntranetLoanDealPreStateId) AS TodayCount
FROM
dbo.TableC ILDPST
LEFT JOIN
dbo.TableB ILDPS ON ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId
LEFT JOIN
dbo.TableA ILDP ON ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId
AND (ILDP.CreatedByDepartmentId = #DepartmentId OR #DepartmentId IS NULL)
WHERE
ILDPST.IntranetLoanDealPreStateTypeId
IN (
SELECT value
FROM dbo.StringAsIntTable(#StatusIds)
)
GROUP BY ILDPST.name;
You could use the following function to create a table value for your status id's.
CREATE FUNCTION [dbo].[SplitString]
(
#myString varchar(max),
#deliminator varchar(2)
)
RETURNS
#ReturnTable TABLE
(
[Part] [varchar](max) NULL
)
AS
BEGIN
Declare #iSpaces int
Declare #part varchar(max)
--initialize spaces
Select #iSpaces = charindex(#deliminator,#myString,0)
While #iSpaces > 0
Begin
Select #part = substring(#myString,0,charindex(#deliminator,#myString,0))
Insert Into #ReturnTable(Part)
Select #part
Select #myString = substring(#mystring,charindex(#deliminator,#myString,0)+ len(#deliminator),len(#myString) - charindex(' ',#myString,0))
Select #iSpaces = charindex(#deliminator,#myString,0)
end
If len(#myString) > 0
Insert Into #ReturnTable
Select #myString
RETURN
END
This can now be used as a table that you can LEFT JOIN to.
DECLARE #StatusIds NVARCHAR(MAX) = '1,2,3,4,5';
SELECT * FROM dbo.SplitString(#StatusIds, ',')
It is not tested but give it a try:
;With Cte ( Value ) As
( Select Distinct Value From dbo.StringAsIntTable( #StatusIds ) )
Select
ILDPST.name,
COUNT(*) AS TodayCount
From
dbo.TableC As ILDPST
Inner Join Cte On ( ILDPST.IntranetLoanDealPreStateTypeId = Cte.Value )
Left Join dbo.TableB As ILDPS On ( ILDPST.IntranetLoanDealPreStateTypeId = ILDPS.CurrentStateTypeId )
Left Join dbo.TableA As ILDP On ( ILDPS.IntranetLoanDealPreStateId = ILDP.IntranetLoanDealPreStateId )
And ( ( ILDP.CreatedByDepartmentId = #DepartmentId ) Or ( #DepartmentId Is Null ) )
Group By
ILDPST.name