I am creating a field by performing some calculations.
Then in the next iteration I use that result to compute a new value. Currently doing this with a WHILE loop. Any other way?
I have tried LAG and Partition and even a recursive CTE but could not achieve the same outcome:
DECLARE #Period INT = 2;
DECLARE #MaxPeriod INT;
SELECT #MaxPeriod = Periods FROM dbo.Engine (NOLOCK);
WHILE (#Period <= #MaxPeriod)
BEGIN
WITH CTE AS (
SELECT
A.ProjectId, A.TypeId, A.Trial, A.Period,
((B.ValueA * (COALESCE(B.FactorCalculated, 0) + 1)) +
(A.ValueA * 0)) / A.ValueA AS FactorCalculated
FROM dbo.PenetrationResults A (NOLOCK)
INNER JOIN dbo.PenetrationResults B (NOLOCK)
ON A.ProjectId = B.ProjectId
AND A.TypeId = B.TypeId
AND A.Trial = B.Trial
AND (A.Period - 1) = B.Period
WHERE A.[Period] = #Period
AND A.ProjectId = #ProjectId
)
UPDATE [target]
SET FactorCalculated = CTE.FactorCalculated
FROM dbo.PenetrationResults AS [target] --(TABLOCK)
INNER JOIN CTE
ON [target].[ProjectId] = CTE.ProjectId AND [target].[TypeId] = CTE.TypeId
AND [target].[Trial] = CTE.Trial
AND [target].[Period] = CTE.Period
SET #Period = #Period + 1
END ;
Well I found a way to make this work using the CTE recursive abilities finally, improved performance 4 x
WITH ncte AS (
-- number the rows sequentially without gaps
SELECT
ProjectId,
TypeId,
Trial,
[Period],
FactorWifiCumulative--,
--FactorConnectedCalc
FROM dbo.PenetrationResults (NOLOCK)
WHERE ProjectId = #ProjectId
), rcte AS (
-- find first row in each group
SELECT *, CAST(0 AS DECIMAL(21,14)) AS Calc
FROM ncte AS base
WHERE Period = 1
UNION ALL
-- find next row for each group from prev rows
SELECT curr.*,
CAST(
(
(
prev.FactorWifiCumulative
*
(
COALESCE(prev.Calc,0)
+ 1
)
)
+
(
curr.FactorWifiCumulative*0
)
)
/
curr.FactorWifiCumulative AS DECIMAL(21,14))
AS Calc
--CAST(prev.Calc * (1 + curr.FactorWifiCumulative / 100) AS DECIMAL(21, 14))
FROM ncte AS curr
INNER JOIN rcte AS prev
ON curr.Period = prev.Period + 1
AND curr.TypeId = prev.TypeId
AND curr.Trial = prev.Trial
)
UPDATE [target]
SET [FactorConnectedCalc] = [Calc]
FROM dbo.PenetrationResults AS [target] (NOLOCK)
INNER JOIN rcte
ON [target].[ProjectId] = rcte.ProjectId
AND [target].[TypeId] = rcte.TypeId
AND [target].[Trial] = rcte.Trial
AND [target].[Period] = rcte.Period
OPTION(MAXRECURSION 0);
I am creating a function that contains a temporary table, it is a bit difficult for me to use the function with a temporary table, I totally do not know if it is allowed within a function since I am new to the new one.
The function I am trying to create is the following:
CREATE FUNCTION FunctionTest (
#Anio int=null,
#Mes int=Null,
#Meses int=6
)
RETURNS #Tabla TABLE (
AnioMes INT,
Viaje VARCHAR(30),
IdPorte INT,
Carga VARCHAR(20),
Peso numeric(32, 16)
)
AS
BEGIN
Declare #AnioMes varchar(8),
#AnioMes6 varchar(8)
if #Anio is null
Select #Anio = YEAR(GETDATE()),
#Mes = MONTH(GETDATE())
Select #AnioMes = (case when #Mes=12 then #Anio+1 else #Anio end *100 + Case when #Mes=12 then 1 else #Mes+1 end)*100 + 1
Select #AnioMes6 = convert(varchar(8), DATEADD(mm, -#Meses, #AnioMes), 112 )
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
into #Temp
FROM BDNEW.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
if #AnioMes6 < '20160101'
insert #Temp
SELECT Year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
FROM BDOLD.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
Delete #Temp
where viaje in (
select MAX(Viaje)
from #Temp
group by IdPorte
having COUNT(IdPorte) > 1
)
Select AnioMes,
Viaje,
IdPorte,
Carga,
Peso,
from #Temp
GROUP BY AnioMes,IdPorte Viaje, Carga, Peso
ORDER BY AnioMes,IdPorte
RETURN
END
If you notice I am making use of a temporary table called #Temp.
As an error message when trying to compile the function I get the following error message:
Cannot access temporary tables from within a function.
That is why I mentioned earlier if you can really make use of temporary tables in a function.
I appreciate anyone who can give me guidance on how to handle this function.
You either use
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
Or
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
Not both:
INSERT INTO #Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
And also you can't use temp tables in functions.
;WITH #SearchHistory (OrderDetail_ID, RelatedOrderDetail_ID, OrigOrderDetail_ID, TimesRolled) AS
(
SELECT od.OrderDetail_ID
,od.RelatedOrderDetail_ID
,0
,0
FROM #SearchFilter f1
INNER JOIN RLHistory.dbo.TRRawDetail od (NOLOCK)
ON od.ConfirmationNo LIKE f1.OrigConfirmationNo + '%'
AND od.ConfirmationNo <> f1.ConfirmationNo
AND od.ItemType_ID IN (14,27)
UNION ALL
SELECT od.OrderDetail_ID
,od.RelatedOrderDetail_ID
,0
,0
FROM #SearchFilter f1
INNER JOIN RueschLink.dbo.ClientOrder co (NOLOCK)
ON co.ConfirmationNo LIKE f1.OrigConfirmationNo + '%'
AND co.ConfirmationNo <> f1.ConfirmationNo
INNER JOIN RueschLink.dbo.OrderDetail od (NOLOCK)
ON od.ClientOrder_ID = co.ClientOrder_ID
AND od.ItemType_ID IN (14,27)
UNION ALL
SELECT od.OrderDetail_ID
,od.RelatedOrderDetail_ID
,CASE WHEN ISNULL(f2.RelatedOrderDetail_ID, 0) = 0 THEN f2.OrderDetail_ID ELSE f2.OrigOrderDetail_ID END
,f2.TimesRolled + 1 - (CASE WHEN ItemType_ID IN (14,27) THEN 0 ELSE 1 END)
FROM #SearchHistory AS f2
INNER JOIN RueschLink.dbo.OrderDetail od (NOLOCK)
ON od.RelatedOrderDetail_ID = f2.OrderDetail_ID
AND od.ItemType_ID IN (14,27,82,83)
UNION ALL
SELECT od.OrderDetail_ID
,od.RelatedOrderDetail_ID
,CASE WHEN ISNULL(f2.RelatedOrderDetail_ID, 0) = 0 THEN f2.OrderDetail_ID ELSE f2.OrigOrderDetail_ID END
,f2.TimesRolled + 1 - (CASE WHEN ItemType_ID IN (14,27) THEN 0 ELSE 1 END)
FROM #SearchHistory AS f2
INNER JOIN RLHistory.dbo.TRRawDetail od (NOLOCK)
ON od.RelatedOrderDetail_ID = f2.OrderDetail_ID
AND od.ItemType_ID IN (14,27,82,83)
)
-- create the report list and use it to collect more details
INSERT INTO #ReportList
(OrderDetail_ID
,RelatedOrderDetail_ID
,OrigOrderDetail_ID
,ConfirmationNo
,OrigConfirmationNo
,TimesRolled
,Reissue)
SELECT f1.OrderDetail_ID
,f1.RelatedOrderDetail_ID
,MAX(f2.OrigOrderDetail_ID)
,f1.ConfirmationNo
,f1.OrigConfirmationNo
,ISNULL(MAX(f2.TimesRolled), 0)
,CASE WHEN ISNULL(MAX(f2.TimesRolled), 0) > 0 THEN 'Y' ELSE 'N' END
FROM #SearchFilter f1
LEFT JOIN #SearchHistory f2
ON f1.OrderDetail_ID = f2.OrderDetail_ID
GROUP BY f1.ConfirmationNo, f1.OrigConfirmationNo, f1.OrderDetail_ID, f1.RelatedOrderDetail_ID
ORDER BY f1.ConfirmationNo
CREATE TABLE #ReportDetails
(
ClientOrder_ID INT
,ConfirmationNo VARCHAR(17)
,ConfirmationNo1 VARCHAR(100)
,OrigConfirmationNo VARCHAR(17)
,ClientName VARCHAR(90)
,Account VARCHAR(100)
,CurrencyCode VARCHAR(17)
,Amount VARCHAR(30)
,SettlementCurrencyCode VARCHAR(17)
,SettlementAmount VARCHAR(30)
,ItemRate VARCHAR(15)
,NewValueDate DATE
,OrigValueDate DATE
,OrderDate DATE
,OrderType VARCHAR(100)
,BeneficiaryName VARCHAR(140)
,OrderSource VARCHAR(100)
,Enteredby VARCHAR(100)
,Reissue VARCHAR(3) DEFAULT 'N'
,TimesRolled INT
,NumberofDaysRolled INT
,Trader VARCHAR(90)
,Trader_ID INT
,Comment VARCHAR(100)
,OrderDetail_ID INT
,WeightedAverage CHAR(1) DEFAULT ''
,OrigOrderDetail_ID INT
,OptionID Varchar(100)
,OriginalAmount VARCHAR(30)
,NewCloseDate Date
,CompletedTenor varchar(30)
,OriginalBookingDate Date
)
--start building the report
INSERT INTO #ReportDetails
(ClientOrder_ID
,ConfirmationNo
,ConfirmationNo1
,OrigConfirmationNo
,ClientName
,Account
,CurrencyCode
,Amount
,SettlementCurrencyCode
,SettlementAmount
,ItemRate
,NewValueDate
,OrderDate
,OrderType
,BeneficiaryName
,OrderSource
,Enteredby
,Reissue
,TimesRolled
,Trader_ID
,Comment
,OrderDetail_ID
,OrigOrderDetail_ID
,OptionID
,OriginalAmount
,NewCloseDate
,CompletedTenor
,OriginalBookingDate)
SELECT
od.ClientOrder_ID
,rl.ConfirmationNo
,('6' + ',' + ltrim(rtrim(Str(ISNULL(od.OrderDetail_ID, 0)))) + ',' + ltrim(rtrim(Str(ISNULL(od.ClientOrder_ID, 0)))) + ',' + ltrim(rtrim(od.ConfirmationNo)) + ',%' + ltrim(rtrim(od.ItemNo))) --link confirmation no
,rl.OrigConfirmationNo
,c.DESCRIPTION -- ClientName
,UPPER(co.Account) -- Account
,od.CurrencyCode -- CurrencyCode
,LTRIM(STR(od.ForeignAmount, 30, ISNULL(od.ForeignAmt_NDec, 2)))-- Amount
,co.Settlement_SWIFT-- SettlementCurrencyCode
,LTRIM(STR(od.Extension, 30, ISNULL(co.SettlementAmt_NDec, 2))) --Settlement Amount
,LTRIM(STR(od.ItemRate, 15, ISNULL(od.ItemRate_NDec, 2))) -- ItemRate
,COALESCE(trdvd.RequestedValueDate, od.ReleaseDate) -- NewValueDate
,co.Ordered -- OrderDate
,ot.DESCRIPTION -- OrderType
,od.BeneName -- BeneficiaryName
,COALESCE(a.Description, a2.Description, #RepoOrderSource) -- OrderSource
,co.UserName -- Enteredby
,rl.Reissue
,rl.TimesRolled
,COALESCE(qh.updid, qh.User_ID, qh.initid, q.updid, q.User_ID, q.initid, co.initid) -- Trader_ID
,rsr.Instructions
,CASE WHEN od.FundedBy = #FundedByMultiple THEN od.OrderDetail_ID ELSE 0 END
,rl.OrigOrderDetail_ID
,(CASE WHEN co.ordertype_id in (6,45,5,11) THEN odOrg.OptionContractId ELSE NULL END) --new column added for PBR-1192
,(CASE WHEN co.ordertype_id in (6,45,5,11) THEN LTRIM(STR(odOrg.ForeignAmount, 30, ISNULL(odOrg.ForeignAmt_NDec, 2))) ELSE NULL END)--new column added for PBR-1192
,(CASE WHEN co.ordertype_id in (6,45,5,11) THEN od.ReleaseDate + od.WindowLength ELSE null END) --new column added for PBR-1192
,(CASE WHEN co.ordertype_id in (6,45,5,11) THEN DateDiff(day,coOrg.Ordered,(od.ReleaseDate + isnull(od.WindowLength,0))) ELSE NULL END) --new column added for PBR-1192
,(CASE WHEN co.ordertype_id in (6,45,5,11) THEN coOrg.Ordered ELSE NULL END) --new column added for PBR-1192
FROM #ReportList rl
INNER JOIN RLHistory.dbo.TRRawDetail od (NOLOCK) ON rl.OrderDetail_ID = od.OrderDetail_ID
INNER JOIN RLHistory.dbo.TRRawHeader co (NOLOCK) ON co.ClientOrder_ID = od.ClientOrder_ID
INNER JOIN RueschLink.dbo.Client AS c (NOLOCK) ON co.Client_ID = c.Client_ID
INNER JOIN RueschLink.dbo.OrderType AS ot (NOLOCK) ON co.OrderType_ID = ot.OrderType_ID
LEFT OUTER JOIN RueschLink.dbo.Application AS a (NOLOCK) ON (co.Application_ID = a.Application_ID AND a.Application_ID = 3)-- a.Description = #FwdOrderSource)
LEFT OUTER JOIN VMaRS.dbo.RSRepurchase AS rsr (NOLOCK) ON rsr.ClientOrder_ID = od.ClientOrder_ID
LEFT OUTER JOIN RueschLink.dbo.Application AS a2 (NOLOCK) ON a2.Application_ID = rsr.ApplicationID
LEFT OUTER JOIN crs..Quote q (NOLOCK) ON od.Quote_ID = q.Quote_ID
LEFT OUTER JOIN crs..QuoteHistory qh (NOLOCK) ON od.Quote_ID = qh.Quote_ID
LEFT OUTER JOIN RLHistory.dbo.TRRawDetailValueDate AS trdvd (NOLOCK) ON od.OrderDetail_ID = trdvd.OrderDetail_ID
LEFT JOIN RLHistory.dbo.TRRawDetail odOrg (NOLOCK) ON odOrg.OrderDetail_ID=RueschLink.dbo.ReturnParentOrderDetailID (od.RelatedOrderDetail_ID) --Join Added for PBR-1192
AND od.RelatedOrderDetail_ID>0 AND od.RelatedOrderDetail_ID IS NOT NULL
LEFT JOIN RLHistory.dbo.TRRawHeader coOrg (NOLOCK) ON coOrg.ClientOrder_ID = odOrg.ClientOrder_ID --Join Added for PBR-1192
ORDER BY co.ConfirmationNo --order the confirmation number asc
I have written the following script to mimic the incoming parameters from datatables and try to filter the results using the parameters. Everything works fine except the order by clause. Basically it only orders by rownumber and does not take into consideration the case statement which provides the second order by column.
declare #sSortColumn as nvarchar(50)='Country';
declare #sSortDirection as nvarchar(5) = 'Desc';
declare #sSearch as nvarchar(50) = '';
declare #iDisplayLength as int = 20;
declare #iDisplayStart as int = 20;
declare #sIDsearch as int = CASE WHEN ISNUMERIC(#sSearch) = 1 THEN CAST(#sSearch AS INT) ELSE 0 END;
WITH media AS
(
select ROW_NUMBER() OVER (ORDER BY mc.id) as RowNumber,
mc.id,mc.Name, mc.CityID,lc.Name as Country
from Lookup_MediaChannels mc
left join Lookup_SonarMediaTypes st on mc.SonarMediaTypeID = st.ID
left join Lookup_SonarMediaGroups sg on sg.ID = st.SonarMediaGroupID
left join Lookup_MediaTypes mt on mc.MediaTypeID = mt.ID
left join Lookup_SonarMediaGroups sg1 on sg1.ID = mt.MediaGroupID
left join lookup_Countries lc on lc.id = mc.countryid
where mc.Name like '%'+#sSearch+'%'
and (sg1.ID=1 or sg.ID =1 )
or mc.id = #sIDsearch
)
SELECT RowNumber, Name, Country
FROM media
WHERE RowNumber BETWEEN (#iDisplayStart+ 1) AND (#iDisplayStart+ #iDisplayLength)
order by rownumber,
CASE WHEN #sSortColumn = 'Name' AND #sSortDirection = 'Desc'
THEN Name END DESC,
CASE WHEN #sSortColumn = 'Name' AND #sSortDirection != 'Desc'
THEN Name END,
CASE WHEN #sSortColumn = 'Country' AND #sSortDirection = 'Desc'
THEN Country END DESC,
CASE WHEN #sSortColumn = 'Country' AND #sSortDirection != 'Desc'
THEN Country END
This simplified example may help you
http://sqlfiddle.com/#!6/35ffb/10
Set up some dummy data (this would be replaced by your select statement)
create table x(
id int,
name varchar(3),
country varchar(2)
)
insert into x
values (1,'aaa','uk'),
(2,'aaa','us'),
(3,'baa','uk'),
(4,'caa','uk'),
(5,'baa','it')
Some vars to hold sort field and sort order
declare #so char(1)
declare #sf char(1)
set #so = 'a' -- a = asc d = desc
set #sf = 'n' -- n = name c = country
and a select to return sorted data
SELECT row_number()
OVER (order by
CASE WHEN #so = 'd' THEN sf END desc,
CASE WHEN #so <> 'd' THEN sf end,
id
) AS aa, name,country
FROM (
SELECT x.*, case #sf when 'n' then name when 'c' then country end sf
FROM X
) X
First and foremost, the SQL is handled dynamically by the server, therefore some items in my WHERE clause may look odd to you, please disregard these as they are not an issue.
Per my clients request, they needed to UNION in two other conditions to my update report (/Patients without a Patient Visit/) and (/Patients without a Appointment/). I need help adding in the patients of these two subsets into my final update query. In its present state, it's only adding in the #Temp patients and I need to incorporate the additional patients.
Any help is GREATLY appreciated.
My current SQL update -
DECLARE #Inactive INT
DECLARE #Active INT
DECLARE #PatientProfileId INT
SELECT
#Inactive = MedlistsId
FROM
Medlists
WHERE
TableName = 'PatientProfileStatus'
AND Code = 'I'
SELECT
#Active = MedlistsId
FROM
Medlists
WHERE
TableName = 'PatientProfileStatus'
AND Code = 'A'
CREATE TABLE #Temp
(
PatientName VARCHAR(120) ,
PatientProfileId INT ,
RecentId INT ,
Recent DATETIME
)
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
MAX(pv.PatientVisitId) AS RecentId ,
MAX(pv.Visit) AS Recent
FROM
PatientVisit pv
INNER JOIN PatientProfile pp ON pv.PatientProfileId = pp.PatientProfileId
AND pp.PatientStatusMId = #Active
WHERE
pp.PatientProfileId IN ( SELECT
a.OwnerId
FROM
Appointments a
INNER JOIN PatientProfile pp ON a.OwnerId = pp.PatientProfileId
AND a.ApptKind = 1
AND pp.PatientStatusMId = #Active
GROUP BY
a.OwnerId ,
a.ApptKind
HAVING
MAX(a.ApptStart) < '07/30/2005' )
GROUP BY
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) ,
pp.PatientProfileId
HAVING
MAX(pv.Visit) < '07/30/2005'
/*Patients without a Appointment*/
IF 1 = 1
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
NULL AS RecentId ,
NULL AS Recent
FROM
PatientProfile pp
LEFT JOIN ( SELECT * FROM Medlists WHERE TableName = 'PatientProfileStatus' ) ml1 ON pp.PatientStatusMId = ml1.MedlistsId
LEFT JOIN Appointments a ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
LEFT JOIN PatientVisit pv ON a.PatientVisitId = pv.PatientVisitId
WHERE
ml1.Code = 'A'
AND a.ownerid IS NULL
AND --Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
/*Patients without a Patient Visit*/
IF 0 = 1
INSERT INTO #Temp
SELECT
dbo.FormatName(pp.Prefix , pp.First , pp.Middle , pp.Last , pp.Suffix) AS Name ,
pp.PatientProfileId ,
NULL AS RecentId ,
NULL AS Recent
FROM
PatientProfile pp
LEFT JOIN PatientVisit pv ON pv.PatientProfileid = pp.PatientProfileid
LEFT JOIN ( SELECT * FROM Medlists WHERE TableName = 'PatientProfileStatus' ) ml1 ON pp.PatientStatusMId = ml1.MedlistsId
WHERE
ml1.Code = 'A'
AND pv.patientprofileid IS NULL
AND --Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
DECLARE curPatient CURSOR FORWARD_ONLY READ_ONLY LOCAL
FOR
SELECT
t.PatientProfileId
FROM
#Temp t
JOIN PatientProfile pp ON t.PatientProfileId = pp.PatientProfileId
JOIN PatientVisit pv ON pp.PatientProfileId = pv.PatientProfileId
AND pv.PatientVisitId = t.RecentId
WHERE
--Filter on Age
(
((
'-1' = '-1'
AND '40' = '125'
)
OR ( CAST(( DATEDIFF(DAY , pp.Birthdate , GETDATE()) / 365.25 ) AS INT) BETWEEN ( '-1' ) AND ( '40' ) ))
)
OPEN curPatient
FETCH NEXT FROM curPatient INTO #PatientProfileId
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE
PatientProfile
SET
PatientStatusMId = #Inactive ,
pstatus = 'I'
FROM
PatientProfile P
INNER JOIN #Temp t ON t.PatientProfileID = P.PatientProfileID
WHERE
p.PatientProfileId = #PatientProfileId
FETCH NEXT FROM curPatient INTO #PatientProfileId
END
CLOSE curPatient
DEALLOCATE curPatient
DROP TABLE #Temp
This will limit to patients WITH an appointment
LEFT JOIN Appointments a
ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
This will limit to patients WITH a Visit
LEFT JOIN PatientVisit pv
ON pv.PatientProfileid = pp.PatientProfileid
Try
LEFT OUTER JOIN Appointments a
ON a.Ownerid = pp.PatientProfileId
AND a.ApptKind = 1
Where a.Ownerid is null
LEFT OUTER JOIN PatientVisit pv
ON pv.PatientProfileid = pp.PatientProfileid
Where pv.PatientProfileid is null