all groups > sql server programming > november 2004 >
You're in the

sql server programming

group:

Converting Exists and NOT EXISTS into UDF or a View etc..


Converting Exists and NOT EXISTS into UDF or a View etc.. Mark
11/10/2004 7:41:01 PM
sql server programming:
Hi All,

I need a suggestion to modify existing code. Is it possible to modify the
below code to replace EXISTS clause with a UDF where function can use SET
ROWCOUNT 1 etc to return me true or false rather than me using EXISTS AND NOT
EXISTS logic here.

What are the alternatives to avoid using EXISTS AND NOT EXISTS?? I hate
using NOT EXISTS but need suggestions to replace it.

Any help will be greatly appreciated.

declare @portfolio_id NUMERIC
SET @portfolio_id = 90004573
SELECT COUNT(*) FROM
Org
, Issuer
, Debt
, Debt_curn_rating
, mdysid.DBO.portfolio_issuer portfolio_issuer
where portfolio_issuer.portfolio_id = @portfolio_id
and Org.org_id = convert(int,portfolio_issuer.issuer_number)
and Issuer.issr_num = Org.org_id
and (Issuer.fr_ref = "C"
or not exists(
select CFRAME.fr_ref
from Issuer CFRAME
where CFRAME.issr_num = Issuer.issr_num
and CFRAME.fr_ref = "C"
))
and exists(
select Debt.inst_id
from Debt
, Debt_curn_rating
where Debt.issr_num = Org.org_id
and Debt.debt_clss_cd in(73371)
and Debt_curn_rating.inst_id = Debt.inst_id
and Debt_curn_rating.ratg_txt != "NAV"
and Debt_curn_rating.ratg_txt != "TWR"
and (Debt_curn_rating.ratg_txt != "WR"
or datediff(month,Debt_curn_rating.ratg_dt,getdate()) <= 3)
and Debt_curn_rating.watch_indc = "N"
and not exists(
select OTHER.inst_id
from Debt OTHER
, Debt_curn_rating OTHER_curn_rating
where OTHER.issr_num = Org.org_id
and OTHER.debt_clss_cd in(73371)
and OTHER_curn_rating.inst_id = OTHER.inst_id
and OTHER_curn_rating.ratg_txt != "NAV"
and OTHER_curn_rating.ratg_txt != "TWR"
and (OTHER_curn_rating.ratg_txt != "WR"
or datediff(month,OTHER_curn_rating.ratg_dt,getdate()) <= 3)
and OTHER_curn_rating.watch_indc = "N"
and OTHER.inst_id != Debt.inst_id
)
)
and Debt.issr_num = Org.org_id
and Debt.debt_clss_cd in(73371)
and Debt_curn_rating.inst_id = Debt.inst_id
and Debt_curn_rating.ratg_txt != "NAV"
and Debt_curn_rating.ratg_txt != "TWR"
and (Debt_curn_rating.ratg_txt != "WR"
or datediff(month,Debt_curn_rating.ratg_dt,getdate()) <= 3)

Re: Converting Exists and NOT EXISTS into UDF or a View etc.. Uri Dimant
11/11/2004 8:43:58 AM
Mark
Look, UDF is perfoming similar to cursor/loop ,row-by row operation. It is
costly. You want to avoid using UDF on large set data. Actualy EXISTS/NOT
EXISTS checks for a nonempty set and returns (internally) 'TRUE/FALSE'.
Most of SQL Server professionals use EXISTS in correlated subqueries.

If you query works fine ,fast , don't try to replace it with UDF.






[quoted text, click to view]

Re: Converting Exists and NOT EXISTS into UDF or a View etc.. Hugo Kornelis
11/11/2004 10:42:54 AM
[quoted text, click to view]

Hi Mark,

First: unless you're a hobbyist, "I hate using ..." is a very bad
argument. A professional uses what's needed for the job, not what he likes
best.

That being said - there are alternatives and there are cases where using
them is a good idea. The alternatives below can sometimes make a query
that's hard to maintain (due to four levels of nested subqueries) easier
on the eyes. They may also impact performance - sometimes making a query
go faster, sometimes making it slower. If you consider using one of the
alternative approaches, do run some performance tests (with both versions)
th check which one is faster.


NOT EXISTS can usually be replaced by an outer join with a test for NULL:

USE pubs
go
SELECT au_lname, au_fname
FROM authors AS a
WHERE NOT EXISTS (SELECT *
FROM titleauthor AS ta
WHERE ta.au_id = a.au_id)
go
SELECT a.au_lname, a.au_fname
FROM authors AS a
LEFT JOIN titleauthor AS ta
ON ta.au_id = a.au_id
WHERE ta.au_id IS NULL
go

EXISTS can sometimes be replaced by an inner join. However, you should be
very wary of this - you might get more rows than you opted for!

USE pubs
go
SELECT p.pub_name
FROM publishers AS p
WHERE EXISTS (SELECT *
FROM authors AS a
WHERE a.city = p.city)
go
SELECT p.pub_name
FROM publishers AS p
INNER JOIN authors AS a
ON a.city = p.city
go


Another alternative would be to replace [NOT] EXISTS with [NOT] IN. But I
would not recommend using [NOT] IN with a subquery - these queries can't
be changed to match on two or more columns instead of one and especially
the NOT IN version shows some very unexpected behaviour with NULLS - if
you google this group, you'll probably be able to find some references.

Best, Hugo
--

AddThis Social Bookmark Button