Thomas Steffen <[EMAIL PROTECTED]> writes:

> On 4/14/05, [EMAIL PROTECTED]
> <[EMAIL PROTECTED]> wrote:
>> How about these:
>> 
>>   SELECT * from Mactor WHERE id = (SELECT MAX(id) FROM Mactor);
>>   SELECT * from Mactor WHERE id = (SELECT MIN(id) FROM Mactor);
>
> I am working on a similar problem at the moment, but unless I missed
> something, ORDER BY  id LIMIT 1 works fine for me. Is there any
> benefit of one formulation against the other? Is the nested SELECT
> less efficient?  Or are they identical in bytecode? 

EXPLAIN is your friend.  As can be seen by EXPLAINing each query (see below),
there are fewer instructions involved in the one with the subquery, and no
sorts or loops as are done in the initial method.  (Note that I've changed the
maximum value to what fits in a signed 32-bit field since I'm doing this with
2.8.16.  You could try a similar experiment with 3.0.x.  Actually, it looks
like you don't even need the WHERE clause in the original query, and I've
tested that modification at the end of the EXPLAINation below, as well.

> What if id is not unique, and I may have rows with identical id?

The original poster had 'id' as INTEGER PRIMARY KEY so that wouldn't be
possible.  If it is possible, then you'd have to decide what you wanted to do
with multiple results.

    % sqlite :memory:
    SQLite version 2.8.16
    Enter ".help" for instructions
    sqlite> CREATE TABLE Mactor
       ...> (
       ...>   id INTEGER PRIMARY KEY,
       ...>   name TEXT,
       ...>   -- any other fields
       ...>   comment TEXT
       ...> );
    sqlite> explain SELECT * FROM Mactor WHERE id < 2147483647 ORDER BY id DESC 
LIMIT 1;
    addr|opcode|p1|p2|p3
    0|ColumnName|0|0|id
    1|ColumnName|1|0|name
    2|ColumnName|2|1|comment
    3|Integer|-1|0|
    4|MemStore|0|1|
    5|ColumnName|3|0|INTEGER
    6|ColumnName|4|0|TEXT
    7|ColumnName|5|0|TEXT
    8|Integer|0|0|
    9|OpenRead|0|3|Mactor
    10|VerifyCookie|0|31|
    11|Rewind|0|25|
    12|Integer|2147483647|0|2147483647
    13|MemStore|1|1|
    14|Recno|0|0|
    15|MemLoad|1|0|
    16|Ge|0|25|
    17|Recno|0|0|
    18|Column|0|1|
    19|Column|0|2|
    20|SortMakeRec|3|0|
    21|Recno|0|0|
    22|SortMakeKey|1|0|-
    23|SortPut|0|0|
    24|Next|0|14|
    25|Close|0|0|
    26|Sort|0|0|
    27|SortNext|0|32|
    28|MemIncr|0|31|
    29|SortCallback|3|0|
    30|Goto|0|27|
    31|Pop|1|0|
    32|SortReset|0|0|
    33|Halt|0|0|
    sqlite> explain SELECT * from Mactor WHERE id = (SELECT MAX(id) FROM 
Mactor);
    addr|opcode|p1|p2|p3
    0|VerifyCookie|0|31|
    1|Integer|0|0|
    2|OpenRead|1|3|Mactor
    3|Last|1|0|
    4|Recno|1|0|
    5|MemStore|0|1|
    6|Goto|0|7|
    7|Close|1|0|
    8|ColumnName|0|0|id
    9|ColumnName|1|0|name
    10|ColumnName|2|1|comment
    11|ColumnName|3|0|INTEGER
    12|ColumnName|4|0|TEXT
    13|ColumnName|5|0|TEXT
    14|Integer|0|0|
    15|OpenRead|0|3|Mactor
    16|MemLoad|0|0|
    17|MustBeInt|1|23|
    18|NotExists|0|23|
    19|Recno|0|0|
    20|Column|0|1|
    21|Column|0|2|
    22|Callback|3|0|
    23|Close|0|0|
    24|Halt|0|0|
    sqlite>explain SELECT * FROM Mactor ORDER BY id DESC LIMIT 1;
    addr|opcode|p1|p2|p3
    0|ColumnName|0|0|id
    1|ColumnName|1|0|name
    2|ColumnName|2|1|comment
    3|Integer|-1|0|
    4|MemStore|0|1|
    5|ColumnName|3|0|INTEGER
    6|ColumnName|4|0|TEXT
    7|ColumnName|5|0|TEXT
    8|Integer|0|0|
    9|OpenRead|0|3|Mactor
    10|VerifyCookie|0|31|
    11|Rewind|0|20|
    12|Recno|0|0|
    13|Column|0|1|
    14|Column|0|2|
    15|SortMakeRec|3|0|
    16|Recno|0|0|
    17|SortMakeKey|1|0|-
    18|SortPut|0|0|
    19|Next|0|12|
    20|Close|0|0|
    21|Sort|0|0|
    22|SortNext|0|27|
    23|MemIncr|0|26|
    24|SortCallback|3|0|
    25|Goto|0|22|
    26|Pop|1|0|
    27|SortReset|0|0|
    28|Halt|0|0|
    sqlite> 

Reply via email to