:-)
Again, are you sure that 'top 1' is such a bad thing compared to 'when
exists'?
Code these two and check the execution plan against both. These are database
independent so no need for any temp tables, etc.. These simply hit the
master table.
select 1
where (exists (
select *
from master..syscolumns
where id = 1
) )
;
select top 1 id
from master..syscolumns
where id = 1
;
Now, here's where properly coded comes into play since I keep forgetting
that SQL Server doesn't require a 'from' (I bounce between SQL Server,
TeraData and DB2).
select 1
from master..syscolumns
where (exists (
select *
from master..syscolumns
where id = 1
) )
;
So why is 'when exists' so much better from a performance standpoint?
--
Walter Clayton
Any technology distinguishable from magic is insufficiently advanced.
[quoted text, click to view] "Adam Machanic" <amachanic@hotmail._removetoemail_.com> wrote in message
news:%234HFEtoGFHA.3876@TK2MSFTNGP14.phx.gbl...
> "Walter Clayton" <w-claytonNO@SPmvps.AMorg> wrote in message
> news:uVkV2cfGFHA.616@TK2MSFTNGP10.phx.gbl...
>> Sure about that? Explain indicates otherwise.
>>
>> Although a properly coded 'where exists' does stop as soon as something
>> satisfies the where clause, there is only 1 row passed through all stages
>> when using 'top 1'.
>
> What do "properly coded" and "passed through all stages" mean? I'm a
> bit perpelxed as to your opinion; the behavior of EXISTS is well
> documented.
> The presence of any rows (= 1 row) satisfying the condition will stop the
> query engine from having to find any more rows. There is no way to
> improperly code this or break the behavior; it works the same way every
> time.
>
> Take a look at the execution plan output by the following batch, which
> shows that there is no scan of the table abc -- the query engine stops as
> soon as it finds a single row -- the row from the 'select 1'.
>
>
> use tempdb
> go
>
> create table abc(id int)
> go
>
> insert abc values (1)
> go
>
> set statistics profile on
>
> select 1
> where exists
> (select 1
> union all
> select id
> from abc)
> go
>
> drop table abc
> go
>
>
> --
> Adam Machanic
> SQL Server MVP
>
http://www.sqljunkies.com/weblog/amachanic > --
>
>
:-)
[quoted text, click to view] > A) "TOP 1" is nondeterministic without an accompanying ORDER BY
> clause -- this means that EVERY ROW must be accounted for in order to get
> a
> meaningful result
Not according to existing documentation and request analyzer. There's no
'with ties'.
So you code:
select top 1 1
from table
where (col = 'val')
order by col
;
The DB2 equivalent is
select 1
from table
where (col = 'val')
order by col
fetch first 1 row only
;
[quoted text, click to view] > B) "TOP 1" is proprietary -- which only matters since you're such a
> multi-DBMS kinda guy.
There's quite a bit of stuff that DB2 and SQL Server implement that are
conceptually similar yet syntactically different. In fact one of the reasons
why I will use the syntax to limit the number of returned rows is in fact
due to the differences in SQL implementations.
e.g. there is no syntactical equivalent to
select 1
where (exists (
select 1
from tab
where (col = 'val')
) )
;
The closest in DB2 is
select 1
from tab
where (exists (
select 1
from tab
where (col = 'val')
) )
;
...which has some rather obvious problems.
But you're also correct in that Teradata, at present, lacks any syntax to
return a set number of rows.
--
Walter Clayton
Any technology distinguishable from magic is insufficiently advanced.
[quoted text, click to view] "Adam Machanic" <amachanic@hotmail._removetoemail_.com> wrote in message
news:%23vA2GR0GFHA.3628@TK2MSFTNGP15.phx.gbl...
> "Walter Clayton" <w-claytonNO@SPmvpsAM.org> wrote in message
> news:e4GmAuuGFHA.4032@TK2MSFTNGP12.phx.gbl...
>>
>> So why is 'when exists' so much better from a performance standpoint?
>
> A) "TOP 1" is nondeterministic without an accompanying ORDER BY
> clause -- this means that EVERY ROW must be accounted for in order to get
> a
> meaningful result.
>
> B) "TOP 1" is proprietary -- which only matters since you're such a
> multi-DBMS kinda guy.
>
>
> --
> Adam Machanic
> SQL Server MVP
>
http://www.sqljunkies.com/weblog/amachanic > --
>
>
[quoted text, click to view] "Walter Clayton" <w-claytonNO@SPmvpsAM.org> wrote in message
news:%23IoxAA5GFHA.588@TK2MSFTNGP10.phx.gbl...
>
> But you're also correct in that Teradata, at present, lacks any syntax to
> return a set number of rows.
I'm not at all familiar with Teradata. Perhaps you can do something like
this:
SELECT
T1.ColA,
T1.ColB,
T1.ColC
FROM Tbl AS T1
JOIN Tbl AS T2 ON T2.PK <= T1.PK
GROUP BY
T1.ColA,
T1.ColB,
T1.ColC
HAVING COUNT(*) = 1;
.... Assuming that PK is unique, this query will give you the "TOP 1" row
ordered by PK. If PK is nonunique you'd have to add a second column to
break ties... This isn't exactly an efficient technique, but it works for
DBMSs that don't have TOP or FIRST extensions.
--
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic --
I'll have to try that when I get a chance next week. I've had several folks
on the project where I'm currently on contract ask what the equivalent
'top'/'first' function for Teradata was and even though I've only been hands
on with Teradata a bit less than a year I've got a reputation for finding
SQL centric solutions for any platform (except Jet). :-/
Just haven't considered limiting things via join.
Efficiency on Teradata is of secondary concern to a degree. Only becomes are
a consideration once the database exceeds a few million rows.
--
Walter Clayton
Any technology distinguishable from magic is insufficiently advanced.
[quoted text, click to view] "Adam Machanic" <amachanic@hotmail._removetoemail_.com> wrote in message
news:OoNeG4BHFHA.1392@TK2MSFTNGP10.phx.gbl...
> "Walter Clayton" <w-claytonNO@SPmvpsAM.org> wrote in message
> news:%23IoxAA5GFHA.588@TK2MSFTNGP10.phx.gbl...
>>
>> But you're also correct in that Teradata, at present, lacks any syntax to
>> return a set number of rows.
>
> I'm not at all familiar with Teradata. Perhaps you can do something like
> this:
>
> SELECT
> T1.ColA,
> T1.ColB,
> T1.ColC
> FROM Tbl AS T1
> JOIN Tbl AS T2 ON T2.PK <= T1.PK
> GROUP BY
> T1.ColA,
> T1.ColB,
> T1.ColC
> HAVING COUNT(*) = 1;
>
>
> ... Assuming that PK is unique, this query will give you the "TOP 1" row
> ordered by PK. If PK is nonunique you'd have to add a second column to
> break ties... This isn't exactly an efficient technique, but it works for
> DBMSs that don't have TOP or FIRST extensions.
>
>
> --
> Adam Machanic
> SQL Server MVP
>
http://www.sqljunkies.com/weblog/amachanic > --
>
>
Don't see what you're looking for? Try a search.