use column alias in other calculation in sql server 2005 - sql-server-2005

I am working with the following query.I want to use Date_Sent_to_Recorder in my other calculations which follows.I am getting an error "Invalid column name 'Date_Sent_to_Recorder'." People recommended using a CTE for this but i am not able to fit it in this scenerio.I have a correlated subquery which calculates Date_Sent_to_Recorder.Please help.
SELECT
C.Name Client ,
SecONdary_Document.Primary_Document_ID ,
SecONdary_Document.Secondary_Document_Id ,
Primary_Document.State + ',' + GB_Counties.CountyName State ,
Grantor.Name Grantor ,
Loan_Number ,
CONVERT(VARCHAR(10), Primary_Document.PIF_Date, 101) PIF_Date ,
( SELECT CASE WHEN dbo.SECONDARY_DOCUMENT.Status_ID = 21
THEN CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT.Updated_Dt, 101)
ELSE ( SELECT TOP 1
CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt, 101)
FROM dbo.SECONDARY_DOCUMENT_STATUS_HISTORY
WHERE dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Secondary_Document_ID = SecONdary_Document.Secondary_Document_Id
AND SECONDARY_DOCUMENT_STATUS_HISTORY.Status_ID = 21
ORDER BY dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt DESC
)
END
) AS Date_Sent_to_Recorder ,
Satis_TimeFrame ,
CASE WHEN PIF_Date IS NULL
OR Date_Sent_to_Recorder IS NULL THEN NULL
ELSE DATEDIFF(DAY, PIF_Date,
Date_Sent_to_Recorder)
END TotalDays ,
CASE WHEN PIF_Date IS NULL
OR Date_Sent_to_Recorder IS NULL THEN NULL
ELSE CASE WHEN DATEDIFF(DAY, PIF_Date,
ISNULL(Date_Sent_to_Recorder,
GETDATE())) > Satis_TimeFrame
THEN 'N'
ELSE 'Y'
END
END InCompliance ,
Loan_Name ,
Deal_Name ,
Deal.Deal_Id ,
Loan.Loan_Id
FROM Primary_Document
INNER JOIN SecONdary_Document ON SecONdary_Document.Primary_Document_ID = Primary_Document.Primary_Document_ID
INNER JOIN Status ON Status.Status_Id = SecONdary_Document.Status_Id
INNER JOIN GB_Counties ON GB_Counties.CountyId = Primary_Document.County_Id
INNER JOIN Loan ON Loan.Loan_Id = Primary_Document.Loan_Id
EDIT------------
DECLARE #Date_Sent_to_Recorder varchar(10)
SELECT C.Name Client ,
SecONdary_Document.Primary_Document_ID ,
SecONdary_Document.Secondary_Document_Id ,
Primary_Document.State + ',' + GB_Counties.CountyName State ,
Grantor.Name Grantor ,
Loan_Number ,
CONVERT(VARCHAR(10), Primary_Document.PIF_Date, 101) PIF_Date ,
--<START>
--3021,RRaghuvansi,If current status is 21 in SECONDARY_DOCUMENT then take Updated_Dt else take Created_Dt in SECONDARY_DOCUMENT_STATUS_HISTORY with status Out For Recorder
--CONVERT(VARCHAR(20), Recording_Date, 101) AS Recording_Date ,
#Date_Sent_to_Recorder=[dbo].[GET_RecordingDate](SecONdary_Document.Secondary_Document_Id), --<END>
Satis_TimeFrame ,
Loan_Name ,
Deal_Name ,
Deal.Deal_Id ,
Loan.Loan_Id
FROM Primary_Document

Since your schema is sort of unclear, here is a brief sample for the derived table syntax and referencing values from the derived table
Declare #Sample table(id1 int, id2 int, value varchar(20))
insert into #sample values (1,1, 'this')
insert into #sample values(2,2, 'that')
insert into #sample values(3,2, 'the other')
Select t1.ID1, t1.Value, t2.RevVal,
case
when t2.RevVal = 'siht' then 1 else 0
end as RevIsThisBackwards
from #sample t1
inner join (Select id1, reverse(value) as RevVal from #sample) t2
on t1.ID1 = t2.ID1
Results
id VALUES Rev Rev Value is this backwards
1 this siht 1
2 that taht 0
3 the other rehto eht 0
So you'll want to move the calculated column, and sufficient columns to join to into a derived table, in your case it would it would look similar to the below
INNER JOIN Loan ON Loan.Loan_Id = Primary_Document.Loan_Id
INNER JOIN (Select SomPKField, CASE WHEN dbo.SECONDARY_DOCUMENT.Status_ID = 21
THEN CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT.Updated_Dt, 101)
ELSE ( SELECT TOP 1
CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt, 101)
FROM dbo.SECONDARY_DOCUMENT_STATUS_HISTORY
WHERE
dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Secondary_Document_ID = SecONdary_Document.Secondary_Document_Id
AND SECONDARY_DOCUMENT_STATUS_HISTORY.Status_ID = 21
ORDER BY dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt DESC
)
END as Date_Sent_to_Recorder
) as Sub1
on SomeTable.SomePKField = Sub1.SomePKField
**I edit your edit in this edit.**
SELECT C.Name Client ,
SecONdary_Document.Primary_Document_ID ,
SecONdary_Document.Secondary_Document_Id ,
Primary_Document.State + ','
+ GB_Counties.CountyName State ,
Grantor.Name Grantor ,
Loan_Number ,
CONVERT(VARCHAR(10), Primary_Document.PIF_Date, 101) PIF_Date ,
[dbo].[GET_RecordingDate]
(SecONdary_Document.Secondary_Document_Id)
As Date_Sent_To_Recorder
Satis_TimeFrame ,
Loan_Name ,
Deal_Name ,
Deal.Deal_Id ,
Loan.Loan_Id
FROM Primary_Document

You cannot refer to a computed column in other columns of a SELECT. The simplest solution for what you are trying to achieve is to pre-calculate Date_Sent_to_Recorder and store it in a temporary table, then join to that table when doing your main query.
Protip: use proper formatting and table aliases; SQL like you posted is difficult to read, and almost impossible to understand.
Edit: something like this:
create table #temp
( Primary_Document_ID int,
Date_Sent_To_Recorder datetime )
insert #temp
select Primary_Document_ID,
CASE
WHEN dbo.SECONDARY_DOCUMENT.Status_ID = 21
THEN CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT.Updated_Dt, 101)
ELSE
(SELECT TOP 1
CONVERT(VARCHAR(10), dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt, 101)
FROM dbo.SECONDARY_DOCUMENT_STATUS_HISTORY
WHERE dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Secondary_Document_ID = SecONdary_Document.Secondary_Document_Id
AND SECONDARY_DOCUMENT_STATUS_HISTORY.Status_ID = 21
ORDER BY dbo.SECONDARY_DOCUMENT_STATUS_HISTORY.Created_Dt DESC)
END
from SecONdary_Document
-- main select, joining to #temp

Because Date_Sent_to_Recorder depends only on SECONDARY_DOCUMENT & SECONDARY_DOCUMENT_STATUS_HISTORY tables, you can replace SECONDARY_DOCUMENT in the INNER JOIN by the following (which gives you Date_Sent_to_Recorder as a column):
SELECT SD.Primary_Document_ID,
SD.Secondary_Document_Id,
CASE WHEN SD.Status_ID = 21
THEN CONVERT(VARCHAR(10), SD.Updated_Dt, 101)
ELSE CONVERT(VARCHAR(10), SDSH.Created_Dt, 101)
END Date_Sent_to_Recorder
FROM SECONDARY_DOCUMENT SD
INNER JOIN dbo.SECONDARY_DOCUMENT_STATUS_HISTORY SDSH
ON SDSH.Secondary_Document_ID = SD.Secondary_Document_Id
AND SDSH.Status_ID = 21
INNER JOIN (SELECT Secondary_Document_ID, max(Created_Dt) Created_Dt
FROM dbo.SECONDARY_DOCUMENT_STATUS_HISTORY
WHERE Status_ID = 21
GROUP BY Secondary_Document_ID) SDSH2
ON SDSH.Secondary_Document_ID = SDSH2.Secondary_Document_Id
AND SDSH.Created_Dt = SDSH2.Created_Dt
and finally you have:
SELECT C.Name Client,
SecONdary_Document.Primary_Document_ID,
SecONdary_Document.Secondary_Document_Id,
Primary_Document.State + ',' + GB_Counties.CountyName State,
Grantor.Name Grantor,
Loan_Number,
CONVERT(VARCHAR(10), Primary_Document.PIF_Date, 101) PIF_Date,
SecONdary_Document.Date_Sent_to_Recorder,
Satis_TimeFrame,
CASE WHEN PIF_Date IS NULL
OR SecONdary_Document.Date_Sent_to_Recorder IS NULL
THEN NULL
ELSE DATEDIFF(DAY, PIF_Date,
SecONdary_Document.Date_Sent_to_Recorder)
END TotalDays,
CASE WHEN PIF_Date IS NULL
OR SecONdary_Document.Date_Sent_to_Recorder IS NULL THEN NULL
ELSE CASE WHEN DATEDIFF(DAY, PIF_Date,
ISNULL(SecONdary_Document.Date_Sent_to_Recorder
,GETDATE())) > Satis_TimeFrame
THEN 'N'
ELSE 'Y'
END
END InCompliance,
Loan_Name,
Deal_Name,
Deal.Deal_Id,
Loan.Loan_Id
FROM Primary_Document
INNER JOIN (SELECT SD.Primary_Document_ID,
SD.Secondary_Document_Id,
CASE WHEN SD.Status_ID = 21
THEN CONVERT(VARCHAR(10), SD.Updated_Dt, 101)
ELSE CONVERT(VARCHAR(10), SDSH.Created_Dt, 101)
END Date_Sent_to_Recorder
FROM SECONDARY_DOCUMENT SD
INNER JOIN dbo.SECONDARY_DOCUMENT_STATUS_HISTORY SDSH
ON SDSH.Secondary_Document_ID = SD.Secondary_Document_Id
AND SDSH.Status_ID = 21
INNER JOIN (SELECT Secondary_Document_ID, max(Created_Dt) Created_Dt
FROM dbo.SECONDARY_DOCUMENT_STATUS_HISTORY
WHERE Status_ID = 21
GROUP BY Secondary_Document_ID) SDSH2
ON SDSH.Secondary_Document_ID = SDSH2.Secondary_Document_Id
AND SDSH.Created_Dt = SDSH2.Created_Dt) SecONdary_Document
ON SecONdary_Document.Primary_Document_ID
= Primary_Document.Primary_Document_ID
INNER JOIN Status ON Status.Status_Id = SecONdary_Document.Status_Id
INNER JOIN GB_Counties ON GB_Counties.CountyId = Primary_Document.County_Id
INNER JOIN Loan ON Loan.Loan_Id = Primary_Document.Loan_Id

Related

How to write below query in PostgreSQL?

I am migrating procedure from SQL Server to PostgreSQL. I can not write this query in PostgreSQL. How to use temp within WITH clause in PostgreSQL?
WITH TEMP AS
(
SELECT a.AssignNo as LowestAssignNo
, a.AssignNo
, a.AssignName
, HierarchyLevel
, UpperAssignNo
FROM TAssignInfo a
WHERE DeleteYesNo = 'N'
AND UseYesNo = 'Y'
UNION ALL
SELECT a.LowestAssignNo
, b.AssignNo
, b.AssignName
, b.HierarchyLevel
, b.UpperAssignNo
FROM TEMP a
INNER JOIN TAssignInfo b
ON a.UpperAssignNo = b.AssignNo
WHERE DeleteYesNo = 'N'
AND UseYesNo = 'Y'
)
SELECT DISTINCT LowestAssignNo
, STUFF(( SELECT '|' + AssignName
FROM TEMP A
WHERE a.LowestAssignNo = b.LowestAssignNo
AND HierarchyLevel > 1
ORDER BY HierarchyLevel
FOR XML PATH('')
), 1, 1, '') AS AssignNamePath
INTO #NewAssignInfo
FROM TEMP B
WHERE B.HierarchyLevel <> 0
ORDER BY LowestAssignNo DESC
enter image description here

Add percentage on every columns on pivot table

******Here is below query for your knowledge how to add percentge columns on every pivot columns let you give the answer 1
I've created a SQL pivot and want to add a further calculated percentage column based on the aggregated figures within and I cannot figure out how to make this happen.****
DELETE TOP(100) PERCENT FROM PlusRS.rpt.RepairLevel
-- STEP NO. 2
INSERT INTO PlusRS.rpt.RepairLevel (ProgramID, PartNo, SerialNo, InvoiceFamily, RepairLevel)
SELECT WOH.ProgramID
, WOH.PartNo
, WOH.SerialNo
, PNA.Value AS InvoiceFamily
, CASE WOH.RepairTypeID WHEN 42 THEN '1'
WHEN 71 THEN '3'
ELSE MAX(PLVL.Value)
END AS RepairLevel
FROM pls.WOHeader WOH
INNER JOIN pls.WOStationHistory WSH ON WOH.ID = WSH.WOHeaderID
INNER JOIN pls.CodeRepairType CRT ON CRT.ID = WOH.RepairTypeID
INNER JOIN pls.WOLine WOL ON WOL.WOHeaderID = WOH.ID AND WOL.StatusID = 14
LEFT JOIN pls.PartNoAttribute PNA ON PNA.AttributeID = 354 AND PNA.ProgramID = WOH.ProgramID AND PNA.PartNo = WOH.PartNo
LEFT JOIN pls.PartNoAttribute PLVL ON PLVL.AttributeID = 149 AND PNA.ProgramID = WOH.ProgramID AND PLVL.PartNo = WOL.ComponentPartNo
WHERE WSH.IsPass = 1 AND WSH.WorkStationID = 2 AND WOH.StatusID != 3
AND woh.ProgramID = '10001' and CONVERT(Date, WSH.lastactivitydate) >= '2022.04.11 ' AND CONVERT(Date, WSH.lastactivitydate) <= '2022.06.15'
GROUP BY WOH.ProgramID
, WOH.PartNo
, WOH.SerialNo
, PNA.Value
, WOH.RepairTypeId
UPDATE PlusRS.rpt.RepairLevel SET BCRatio = CASE WHEN RepairLevel = '0' THEN 9
WHEN RepairLevel = '1' THEN 0
WHEN RepairLevel = '2' THEN 53
WHEN RepairLevel = '2.5' THEN 0
WHEN RepairLevel = '3' THEN 38
WHEN RepairLevel = 'O' THEN 0
END
Declare #sqlquery nvarchar(max),
#column nvarchar(max);
SELECT #column = COALESCE(#column + ',', '') + QUOTENAME(InvoiceFamily)
FROM
(
SELECT Distinct InvoiceFamily
FROM PlusRS.rpt.RepairLevel
) AS PIVOT_COLUMNS
DECLARE #ColumnForSum AS NVARCHAR(MAX)
SELECT #ColumnForSum =REPLACE(#column,',','+')
SELECT #ColumnForSum =REPLACE(#ColumnForSum,'[','ISNULL([')
SELECT #ColumnForSum =REPLACE(#ColumnForSum,']','],0)')
SET #sqlquery =
N'select * into #TempBag from
(
SELECT SerialNo as Qty
, InvoiceFamily
, RepairLevel
, BCRatio
FROM
PlusRS.rpt.RepairLevel
)as t
pivot(
count(qty)
for InvoiceFamily In('+#column+')
)As Pvt_table
ORDER BY RepairLevel
select t.*, SUM('+#ColumnForSum+') Total from #TempBag t
GROUP BY RepairLevel,BCRatio,'+#column+'
Drop Table #TempBag'
EXEC sp_executesql #sqlquery**

How to increase speed of stored procedure when using order by statement?

I have a stored procedure that returns almost 16000 rows. It also has pagination and returns 10 rows on each page.
This procedure returns user's tickets; when I use order by for sorting them, its execution speed slows down. I checked the execution plan but I don't get useful information, and just I got that order by has warning that operator used tempdb to spill data during execution with spill level 1 and 1 spilled threads, but I don't know how can I solve it.
I would like to know, how can I make my procedure execution faster?
This is my procedure:
;WITH Tickets AS
(
SELECT
t.Id ,
t.[Subject] ,
t.UserId,
t.PriorityId,
u.UserName,
c.[Name] AS UserCompanyName,
t.[Description],
t.LastStatus AS StatusId,
s.[Name] AS [Status],
t.Number AS TicketNumber,
t.CreateOn,
t.CompanyProjectId AS ProjectId ,
(SELECT TOP 1 [Name] FROM CompanyProject
WHERE CrmProjectId = t.CompanyProjectId) AS ProjectName ,
t.[TempNumber],
t.TypeRequestId AS RequestTypeId,
rt.[Name] AS RequestTypeName,
psc.NewMessagesCount,
FORMAT(DATEADD(MINUTE, t.FirstResponsePace, t.CreateOn), 'yyyy/MM/dd HH:mm', 'fa') AS FirstResponsePace,
FORMAT(DATEADD(MINUTE, t.FinishedPace, t.CreateOn), 'yyyy/MM/dd HH:mm', 'fa') AS FinishedPace,
CASE
WHEN t.SlaType IS NULL THEN N'تعیین نشده'
WHEN t.SlaType = '' THEN N'تعیین نشده'
ELSE t.SlaType
END AS SlaType
FROM
Ticket t
LEFT OUTER JOIN
dbo.AspNetUsers u ON t.UserId = u.Id
INNER JOIN
#TempSubUsers tree ON tree.UserId = u.Id
LEFT OUTER JOIN
dbo.AssignmentPosition ap ON u.Id = ap.UserId
LEFT OUTER JOIN
dbo.Company c ON c.id = ap.CompanyId
LEFT OUTER JOIN
dbo.RequestType rt ON rt.Id = t.TypeRequestId
LEFT OUTER JOIN
dbo.[Status] s ON s.Id = t.LastStatus
OUTER APPLY
(SELECT COUNT(1) AS NewMessagesCount
FROM dbo.ProcessStepComment
WHERE EntityId = t.Id AND Seen = 0 AND UserId IS NULL
GROUP BY EntityId) psc
WHERE
(t.Id = #id OR ISNULL(#id, CAST(0x0 AS UNIQUEIDENTIFIER)) = CAST(0x0 AS UNIQUEIDENTIFIER))
AND (t.CreateOn >= #sdate OR ISNULL(#sdate, '') = '')
AND (t.CreateOn <= #edate OR ISNULL(#edate, '') = '')
AND ((t.[Subject] LIKE N'%' + #generalSearch + N'%'
OR t.Number LIKE N'%' + #generalSearch + N'%'
OR t.TempNumber LIKE N'%' + #generalSearch + N'%')
OR ISNULL(#generalSearch, '') = '')
AND (t.LastStatus IN (#allStatusIdListString)
OR (SELECT COALESCE(#allStatusIdListString, CAST(0x0 AS UNIQUEIDENTIFIER))) = CAST(0x0 AS UNIQUEIDENTIFIER))
AND (t.TypeRequestId = #requestTypeId OR
ISNULL(#requestTypeId, #UniqueIdentifierDefault) = #UniqueIdentifierDefault)
AND (t.UserId = #userId OR ISNULL(#userId, '') = '')
AND (t.CompanyProjectId = #companyProject
OR ISNULL(#companyProject, #UniqueIdentifierDefault) = #UniqueIdentifierDefault)
AND (c.Id = #companyId OR ISNULL(#companyId, #UniqueIdentifierDefault) = #UniqueIdentifierDefault)
AND t.[IsEnable] = 1
)
SELECT *
FROM Tickets
ORDER BY
NewMessagesCount DESC,
CASE StatusId
WHEN 'A4E6D31F-ECD1-4288-863F-D4D5449C19D3' THEN 1
WHEN 'EB1566A1-35FD-4C8F-AC27-DB7B02D68299' THEN 2
WHEN '14F7090A-412B-4467-966F-CFEA59F7C434' THEN 3
WHEN 'E9FFB96F-2770-4763-A58D-E363D0903FB4' THEN 4
WHEN 'D002E7AA-2599-4B3C-89E6-DE8A74023E6A' THEN 5
WHEN '1A20087B-D8F1-437F-BC60-4723E5AFEB1A' THEN 6
WHEN '04BE6210-CBF9-4158-A464-7973F4FFDD6F' THEN 7
WHEN 'DF0F6E06-2AEC-4731-86DC-DF25981B852E' THEN 8
WHEN '5635F7AA-37DF-4EFF-B0C7-24E0C3BF4564' THEN 9
ELSE 10
END ASC,
CreateOn DESC
OFFSET #PageSize * (#PageNumber - 1) rows fetch next #PageSize rows ONLY

How to remove the joins in this slow SQL

I have the following (obfuscated) SQL running on SQL Server 2012 and need to significantly improve its performance. It works, but sometimes takes more than 60s to return.
I would like to extract the JOINS but this post seems to indicate that this will not be possible (because of things like MIN and MAX) - so how can improve the performance and get these joins simplified/improved?
SELECT
wm.id, wm.uid, wm.em, wm.fn, wm.ln, c, y, RTRIM(LTRIM(yCode)) AS yCode, wm.d1, ISNULL(wm.ffn, wm.pp) as ffn, wm.ada,
case
when wm.mss & 2=2
then 'false'
else 'true'
end AS isa,
(
SELECT ', '+RTRIM(p1.cKey)
FROM profile p1
inner join loc stl on p1.cKey=stl.cKey
WHERE p1.id = wm.id and p1.s = 'A'
FOR XML PATH('')
) [lst],
lishc.[lstCount],
TotalCount = COUNT(*) OVER(),
la.lsa, wskp.cKey AS pid
FROM wmm wm
LEFT JOIN profile p1 ON wm.id = p1.id
LEFT JOIN (
SELECT UA.id, CONVERT(datetime, UA.ins, 1) As lsa
FROM actlog UA
INNER JOIN (
select id, max(ins) as laa
from actlog
group by id
) UAJ on UA.id=UAJ.id and UA.ins=UAJ.laa
) la on la.id=wm.id
LEFT JOIN (
SELECT id, cKey FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY d1 desc) AS ROWNUM
FROM keypro where sc = 'SAP' AND cKeyDesc = 'SAP Agent ID'
) x WHERE ROWNUM = 1
) wskp ON wskp.id = wm.id
LEFT JOIN (
(SELECT p1.id ,COUNT(p1.cKey) AS [lstCount]
FROM profile p1
inner join loc stl on p1.cKey=stl.cKey
where p1.s = 'A'
GROUP BY p1.id)
) lishc ON lishc.id = wm.id
WHERE (#id = 0 OR wm.id = #id)
AND (#uid IS NULL OR wm.uid LIKE '%' + #uid + '%')
AND (#c IS NULL OR wm.c LIKE '%' + #c + '%')
AND (#fn IS NULL OR wm.fn LIKE '%' + #fn + '%')
AND (#ln IS NULL OR wm.ln LIKE '%' + #ln + '%')
AND (#em IS NULL OR wm.em LIKE '%' + #em + '%')
AND (#ffn IS NULL OR (wm.ffn LIKE '%' + #ffn + '%' OR wm.pp LIKE '%' + #ffn + '%'))
AND (#pid IS NULL OR wskp.cKey LIKE '%' + #pid + '%' )
AND (#Date1 IS NULL OR (CAST(wm.d1 AS DATE) BETWEEN CAST(#Date1 AS DATE) AND CAST(#Date2 AS DATE)))
AND (#lsa1 IS NULL OR (CAST(la.lsa AS DATE) BETWEEN CAST(#lsa1 AS DATE) AND CAST(#lsa2 AS DATE)))
AND (#Active IS NULL OR (wm.mss & 2 != 2))
AND (#Inactive IS NULL OR (wm.mss & 2 = 2))
AND (#External IS NULL OR (wm.ada = 'biz'))
AND (#Internal IS NULL OR (wm.ada <> 'biz'))
AND (#ApplyyFilter =0 OR (wm.yCode IN (SELECT #yCode WHERE 1 = 0)))
AND (#ApplylstFilter = 0 OR(p1.cKey IN (SELECT #ShipToList WHERE 1 = 0)))
AND (#ApplylstFilter = 0 OR(p1.s = 'A'))
AND (#ApplyNoFilter = 0 OR (lishc.[lstCount] is null))
AND (#lstCount = 0 OR lishc.[lstCount] = #lstCount)
AND (#ApplyLimitedFilter = 0 OR (wm.id IN (0)))
AND (#ApplyMoreFilter = 0 OR (wm.id IN (SELECT #idss WHERE 1 = 0)))
GROUP BY wm.id, wm.uid, wm.em, wm.fn, wm.ln, y, yCode,c,wm.d1,wm.ffn,wm.mss,wm.ada, la.lsa, wskp.cKey, lishc.[lstCount], wm.pp
ORDER BY lsa DESC
OFFSET #PageOffset ROWS FETCH NEXT #PageSize ROWS ONLY
The quick hit here is to add OPTION (RECOMPILE) so SQL Server can eliminate the predicates that correspond to null parameters and create a new plan for each search.
And see, generally Dynamic Search Conditions in T‑SQL
The next thing to do is to get rid of the wildcard searches wherever possible.
And transform this
(CAST(la.lsa AS DATE) BETWEEN CAST(#lsa1 AS DATE) AND CAST(#lsa2 AS DATE)))
into a SARGable pattern like
la.lsa >= #lsa1 and la.lsa < #lsa2
Then start to pull this query apart, and hand-write separate queries for the most common or critical cases.

Comma delimiting results of one column to show next to another?

I have a table:
lease_id, suite_id
Lease is a key and you can have multiple suite’s to one lease. I’m trying to create a query that shows me all of the suite’s that a lease is associated with, essentially an output like the following:
lease_id: 1 suite_list: A1, A2, B1
Unfortunately I’m unsure how to approach this (or even how to begin) as this is a new kind of problem for me... Any help would be greatly appreciated!
You can use FOR XML.
The code will be something like this:
-- Sample data tables
select *
into #leases
from (
select '1' as lease_id
union
select '2' as lease_id
) a
select *
into #leaseSuites
from (
select '1' as lease_id,
'A1' as suite_id
union
select '1' as lease_id,
'A2' as suite_id
union
select '1' as lease_id,
'B1' as suite_id
union
select '2' as lease_id,
'C2' as suite_id
union
select '2' as lease_id,
'B3' as suite_id
) a
-- Creates comma delimited with child table.
select left(suite_list, LEN(suite_list) - 1) as suite_list
from (
SELECT 'lease_id: ' + lease_id + ' ' +
'suite_list: ' + (
SELECT s.suite_id + ','
FROM #leaseSuites s
WHERE l.lease_id = s.lease_id
ORDER BY s.suite_id
FOR XML PATH('')
) AS suite_list
FROM #leases l ) a
Click here to see an article with an example.
I'll assume your table is called LeasedSuites.
We'll need a function:
create function dbo.AllSuite (#l int) returns varchar(100)
as begin
declare #v varchar(2);
declare #r varchar(100);
DECLARE sc CURSOR FOR select suite_id from LeasedSuites where lease_id = #l
OPEN sc
FETCH NEXT FROM sc INTO #v
WHILE ##FETCH_STATUS = 0 BEGIN
select #r = #r + ',' + #v;
FETCH NEXT FROM sc INTO #v
END
CLOSE sc
DEALLOCATE sc
return substring(#r, 2, len(#r) - 1);
end
And a query:
declare #l int;
create table #out (lease_id int, suite_str varchar(100) null)
insert #out (lease_id) select distinct lease_id from LeasedSuites
while (select count(*) from #out where suite_str is null) > 0 begin
select #l = min(lease_id) from #out where suite_str is null;
update #out set suite_str = dbo.AllSuite(#l) where lease_id = #l;
end
select 'Lease ID: ' + cast(lease_id as varchar(3)) + ' Suites: ' + suite_str from #out order by l;
Hope this helps. Regards JB
If this represents an answer please mark as answer.
I've ended up solving this in two ways. My first method, which was unfortunately quite slow was:
declare #period_id integer =
(
select period_id
from property.period
where getdate() between period_start and period_end
)
;with cte_data as
(
select lp.*
from property.lease_period lp
where period_id = #period_id
)
, cte_suites as
(
select d.lease_id
, (
select stuff
(
( select ', ' + a.suite_id
from
( select a.suite_id
from cte_data a
where a.lease_id = d.lease_id
) a
for xml path(''))
, 1, 2, ''
) as suite_list
) suite_list
from cte_data d
group by d.lease_id
) ,
cte_count as
(
select lease_id ,
count(suite_id) as 'suites'
from property.lease_period
where period_id = #period_id
and lease_id <> 'No Lease'
group by lease_id
)
select d.period_id ,
d.building_id ,
d.lease_id ,
s.suite_list
from cte_data d
left outer join cte_suites s
on d.lease_id = s.lease_id
inner join cte_count c
on d.lease_id = c.lease_id
where period_id = 270
and d.lease_id <> 'No Lease'
and c.suites > 1
group by
d.period_id ,
d.building_id ,
d.lease_id ,
s.suite_list
I then stripped this back and re-approached it with a new direction, resulting in the following (much, much quicker):
declare #period_id integer =
(
select period_id
from property.period
where getdate() between period_start and period_end
)
;with CteLeaseInMultSuites as
(
select period_id,
building_id,
lease_id
from property.lease_period
where period_id = #period_id
and lease_id <> 'No Lease'
group by
period_id,
building_id,
lease_id
having count(*) > 1
)
select period_id,
building_id,
lease_id,
left(x.suite_list, len(x.suite_list) - 1) as suite_list
from CteLeaseInMultSuites lm
cross apply
(
select suite_id + ', '
from CteLeaseInMultSuites lmx
inner join property.lease_period lp
on lp.period_id = lmx.period_id
and lp.building_id = lmx.building_id
and lp.lease_id = lmx.lease_id
where lmx.period_id = lm.period_id
and lmx.building_id = lm.building_id
and lmx.lease_id = lm.lease_id
for xml path('')
) x (suite_list)